home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Legend / Legend source / Legend.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-31  |  99.0 KB  |  3,768 lines  |  [TEXT/KAHL]

  1. /************************************************************************
  2.  
  3. Legend 1.0.0
  4.  
  5. Legend!! by bohm
  6. now for power pc
  7.  
  8. About Legend Code:
  9. Legend was primarily written before 1992 as my first Macintosh program.  Prior to this I had done
  10. programming for the Atari game machines as well as the Apple II.  I have occassionally updated
  11. the program, most recently to accomodate the callback mechanism required for PowerPC code.
  12.  
  13. While some of the ideas are somewhat primitive, many of the concepts are timeless.  Look at the
  14. picts in Resedit and notice how i index into the master pictures.  The master pictures are kept
  15. in memory at all times in an offscreen bitmap or pixmap for quick access.
  16.  
  17. Earlier Macintoshes did not support Color Quick Draw, so you'll notice there are two sets
  18. of routines for all the copybits operations.  This is no longer an issue in today's machines
  19. and system software so the b/w operations are not necessary; even b/w powerbooks have Color
  20. Quick Draw support.
  21.  
  22. Legend code is for you to study and enjoy as I have learned from others.
  23.  
  24. **************************************************************************/
  25.  
  26.  
  27. #include <Sound.h>
  28. #include <Palettes.h>
  29. #include <Power.h>
  30. #include <GestaltEqu.h>
  31. #include <LowMem.h>
  32.  
  33. #define BASE_RES_ID        400
  34. #define NIL_POINTER        0L
  35. #define    NIL                NIL_POINTER
  36. #define NIL_REF_CON        NIL_POINTER
  37. #define NIL_STRING        "\p"
  38.  
  39. #define MOVE_TO_FRONT    -1L
  40. #define    VISIBLE            TRUE
  41. #define REMOVE_ALL_EVENTS    0
  42.  
  43. #define INCLUDE_SECONDS    TRUE
  44. #define ADD_CHECK_MARK    TRUE
  45. #define REMOVE_CHECK_MARK    FALSE
  46.  
  47. #define DRAG_THRESHOLD    30
  48.  
  49. #define MIN_SLEEP        0L
  50. #define NIL_MOUSE_REGION    NIL
  51.  
  52. #define WNE_TRAP_NUM    0x60
  53. #define UNIMPL_TRAP_NUM    0x9f
  54.  
  55. #define NOT_A_NORMAL_MENU    -1
  56. #define CLOCK_LEFT        12
  57. #define CLOCK_TOP        14
  58. #define CLOCK_SIZE        14
  59. #define ABOUT_ALERT        400
  60.  
  61. #define STATUS_QUIT        0        /*status codes for masterstatus*/
  62. #define STATUS_WAIT        1
  63. #define    STATUS_DEMO        2
  64. #define    STATUS_GAME        3
  65. #define STATUS_NEWGAME    4
  66. #define STATUS_OVER        5
  67.  
  68. #define NUM_OF_BUTTONS        4
  69.  
  70. #define TOCATTA_SND        8192
  71. #define YUM_SND            8193
  72. #define    FOOT_SND        8194
  73. #define ARROW_SND        8195
  74. #define OUCH_SND        8196
  75. #define MONEY_SND        8197
  76. #define KEY_SND            8198
  77. #define BAT_SND            8199
  78. #define UNLOCK_SND        8200
  79. #define POOF_SND        8201
  80. #define EEP_SND            8202
  81.  
  82. /**maximums**/
  83. #define    MAXFINALS        48
  84. #define MAXLEVELS        16
  85. #define MAXMONSTERS        24
  86. #define MAXMISSILES        4
  87. #define MAXHEALTH        128
  88. #define MAXOBJECTS        16
  89.  
  90. #define MAXLWIDTH        24
  91. #define MAXLHEIGHT        16
  92.  
  93. /**objectcodes**/
  94. #define    APPLE            1
  95. #define KEY                2
  96. #define TREASURE        3
  97. #define MACHINE            4
  98. #define KEYHOLE            5
  99. #define GATE            6
  100. #define SUPERAPPLE        7
  101. #define INLETL            8
  102. #define INLETR            9
  103. #define RING            10
  104. /**monstercodes**/
  105. #define    BAT                2
  106. #define DEAD            4
  107. #define GHOST            16
  108. #define POOLBALL        18
  109. #define    ICECREAM        20
  110. #define BUGGLES            32
  111. #define BEHOLD            22
  112. #define BEHOLDH            23
  113. #define EGGLES            24
  114. #define DEADEGGLES        25
  115. /**itemcodes**/
  116. #define KEYITEMA        1
  117. #define RINGITEM        4
  118.  
  119.  
  120. /******************************************/
  121. /*                                        */
  122. /*               Menu Table               */
  123. /*                                        */
  124. /******************************************/
  125.  
  126. /***Apple Menu*****************************/
  127. #define ABOUT_ITEM        1
  128.  
  129. /***File Menu******************************/
  130. #define NEW_ITEM        1
  131. #define OPEN_ITEM        2
  132. #define SAVE_ITEM        3
  133. #define ABORT_ITEM        5
  134. #define QUIT_ITEM        6
  135.  
  136. /***Options Menu***************************/
  137. #define SOUND_ITEM        1
  138. #define SCREENSIZE_ITEM    3
  139.  
  140. /***Miscellaneous Menu*********************/
  141. #define PAUSE_ITEM        1
  142. #define INSTRUCT_ITEM    2
  143.  
  144. /***Size Menu******************************/
  145. #define NATURAL_ITEM    1
  146. #define THE10BY10_ITEM    2
  147. #define THE12BY12_ITEM    3
  148. #define THE14BY13_ITEM    4
  149.  
  150. /***Control Menu***************************/
  151. #define KEYBOARD_ITEM    1
  152. #define MOUSE_ITEM    2
  153.  
  154. /***Menu ID Table**************************/
  155. #define APPLE_MENU_ID    256
  156. #define FILE_MENU_ID    257
  157. #define EDIT_MENU_ID    258
  158. #define OPTIONS_MENU_ID    259
  159. #define MISC_MENU_ID    260
  160. #define SIZE_MENU_ID    100
  161. #define START_MENU_ID    101
  162. #define CONTROL_MENU_ID    102
  163.  
  164. /******************************************/
  165.  
  166.  
  167.  
  168. /***structures***/
  169. struct    finalbox
  170.     {
  171.     int    x,y,size;
  172.     };
  173.  
  174. struct monsterdata
  175.     {
  176.     int    status,dir,x,y,transit,pic;
  177.     int    alt1,alt2;
  178.     };
  179. struct objectdata
  180.     {
  181.     int    status,dir,x,y,transit,pic;
  182.     int    alt1,alt2;
  183.     };
  184. struct missiledata
  185.     {
  186.     int    status,dir,x,y,transit,pic;
  187.     float    alt1,alt2;
  188.     };
  189.  
  190.  
  191. /***Variables***/
  192.  
  193. #ifdef __POWERPC
  194. QDGlobals    qd;
  195. #endif
  196.  
  197. PicHandle    gThePicture;
  198. EventRecord    gTheEvent;
  199. MenuHandle    gAppleMenu,gFileMenu,gOptionsMenu,gMiscMenu,
  200.             gSizeMenu,gStartMenu,gControlMenu;
  201. Rect        gDragRect,gmainrect;
  202. CursHandle    gtargetcursor;
  203.  
  204.  
  205. Rect        gbuttonrect[NUM_OF_BUTTONS];
  206. PicHandle    gbuttonpicu[NUM_OF_BUTTONS];
  207. PicHandle    gbuttonpicd[NUM_OF_BUTTONS];
  208.  
  209. /*char        gtheChar;*/
  210. unsigned char         gkm[16];            /*keymap*/
  211.  
  212. WindowPtr    myWindow;
  213. Rect        globRect,allrect,playrect,trueplayrect;
  214. Rect        sqRect={0,0,256,256};
  215. int            i,err;
  216.  
  217. RgnHandle    playregion;            /*portion of window not incl side panel*/
  218. RgnHandle    mousergn;            /*check for mouse moved events here*/
  219.  
  220. CGrafPort    myCGrafPort;
  221. GrafPort    myGrafPort;
  222. CGrafPtr    myCGrafPtr;
  223. GrafPtr        myGrafPtr;
  224. GDHandle    theMaxDevice,oldDevice;
  225.  
  226. Boolean        colororbw;
  227. Boolean        gsimplesound;
  228. int        gbasepic;            /*resource ID number of color pics*/
  229. int        sizecheck=NATURAL_ITEM;
  230.  
  231. Ptr            mypiximage0,mypiximage1,mypiximage2,mypiximage3,mypiximage4;
  232. Ptr            mybitimage0,mybitimage1,mybitimage2,mybitimage3,mybitimage4;
  233. PixMapHandle    pix1,pix2,pix3,pix4;
  234. BitMap        bit0,bit1,bit2,bit3,bit4,bitmask3,bitmask4;
  235.  
  236. /*
  237.     Piximage:        PixMap:                    Purpose:
  238.     screenbits        myWindow                screen image
  239.     mypiximage0        myCGrafPtr->portBits    primary offscreen grafport
  240.     mypiximage1        pix1                    background landscape
  241.     mypiximage2        pix2                    walls n stuff
  242.     mypiximage3        pix3                    player
  243.     mypiximage4        pix4                    monster A
  244.     
  245.     Bitimage        Bitmap:
  246.     mybitimage0        bit0                    primary offscreen grafport
  247.     mybitimage1        bit1                    background landscape
  248.     mybitimage2        bit2                    walls n stuff
  249.     mybitimage3        bit3                    player
  250.     mybigimage4        bit4                    monster A
  251.     myBitsmask3        bitmask3                mask for pix3
  252.     myBitsmask4        bitmask4                mask for pix4
  253. */
  254.  
  255. /**sound**/
  256. Boolean            soundison;
  257. Handle            tocattahandle,yumhandle,foothandle,arrowhandle,ouchhandle;
  258. Handle            keyhandle,moneyhandle,bathandle,unlockhandle,poofhandle,eephandle;
  259. SndChannelPtr    gsndchannela,gsndchannelb,gsndchannelc;
  260.  
  261. /**Game Variables**/
  262. int            gvara;                /*multipurpose global*/
  263. Boolean        gkeyormouse;        /*0:keyboard 1:mouse*/
  264. int            level;                /*current level*/
  265. int            hlevel;                /*highest level achieved*/
  266. int            startlevel;            /*level desired to start at*/
  267. Boolean        landscaperequest;    /*0:nothing 1:draw landscape*/
  268. Boolean        faderequest;        /*fade or not during uplevel refresh*/
  269. int            masterstatus;        /*0:quit 1:wait 2:demo 3:play*/
  270. int            mapx,mapy;            /*upper left of map in abs coor*/
  271. int            lmapx,lmapy;        /*upper left of map in land coor*/
  272. int            width,height;        /*play area in abs coor*/
  273. int            lwidth,lheight;        /*play area in land coor*/
  274. int            natlwidth,natlheight;    /*natural area*/
  275. Boolean        addmoremon;            /*0:no more monsters 1:space left*/
  276. Boolean        gbonuselg;            /*0:not elgible*/
  277. int            numfinal;            /*number of final transfers*/
  278. int            health,healtht;        /*player health*/
  279. int            pls,pld,plx,ply,plt,plp;            /*player stuff*/
  280. int            nummonsters;        /*current number of monsters*/
  281. int            numobjects;            /*current number of objects*/
  282. int            gnumitems;            /*current number of items*/
  283. int            occumaster;            /*allows variations on occupied*/
  284. int            score;                /*player score*/
  285. int            digit[5];            /*digits of score*/
  286. int            gloop;                /*monster and object loop*/
  287. Boolean        gred;                /*if set draw energy bar red*/
  288. int            gitemlist[16]={0};    /*array of player items*/
  289. int            gatestatus[4];        /*0:locked 1:open*/
  290. int            gcard;                /*card # for help*/
  291. int            gcounter;            /*updated every loop thru main game*/
  292.  
  293.  
  294.  
  295. /** dungeon data**/
  296. int            thislevel[16][24];
  297. Byte        dungeon[MAXLEVELS][16][24]={
  298.             {{0}},
  299.             /*entry:level 1*/
  300.             {{9, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 8},
  301.             {03,00,00,00,00,00,00,03,27,00,00,00,00,00,00,00,03,00,00,00,00,19,20, 3},
  302.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,00,00,00,06,02,02,15},
  303.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  304.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  305.             {13,04,00,06, 2, 2, 2,11,00,00,00,00,00,00,00,00,10,02,02,02,04,00,06,15},
  306.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  307.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  308.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  309.             {03,00,00,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  310.             {13,16,17,18,02,02,02, 8,00,00,00,00,00,00,00,00, 9,02,02,02,04,00,06,15},
  311.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,29,00,00,00,00,00,03},
  312.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  313.             {03,00,00,00,00,24,00,03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  314.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  315.             {10, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2,11}},
  316.             /*level2*/
  317.             {{9, 2, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 2, 8},
  318.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,27,03,00,00,00,00,00,00,00, 3},
  319.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,24,00,00,00,00,00,03},
  320.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,03},
  321.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,03},
  322.             {13,02,02,04,00,06, 2,02,14,04,00,06,02,02,02,14,02,02,04,00,06,02,02,15},
  323.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  324.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  325.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  326.             {03,00,00,00,00,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  327.             {13,04,00,06,02,12,02,16,17,18, 8,00,00, 9,04,00,06,02,12,02,04,00,06,15},
  328.             {03,00,00,00,00,03,00,00,00,00,03,00,00,03,00,00,00,00,03,00,00,00,00,03},
  329.             {03,00,00,00,00,03,00,00,00,00,03,00,00,03,00,00,00,00,03,00,00,00,00,03},
  330.             {03,00,00,00,00,03,00,00,00,00,03,00,00,03,00,00,00,00,03,00,00,06,02,15},
  331.             {03,00,00,00,00,03,32,29,00,00,03,00,28,03,00,00,00,00,03,00,00,19,20,03},
  332.             {10, 2, 2, 2, 2,14, 2, 2, 2, 2,14, 2, 2,14, 2, 2, 2, 2,14, 2, 2, 2, 2,11}},
  333.             /*level3*/
  334.             {{9, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 2,12, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  335.             {03,00,00,00,03,00,00,00,00,00,00,28,03,00,00,00,00,00,00,00,00,00,27, 3},
  336.             {03,00,00,00,03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,00,00, 3},
  337.             {03,00,00,00,03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,00,00, 3},
  338.             {03,00,00,00,03,00,00,00,05,00,00,00,03,00,00,00,05,29,00,00,05,29,00, 3},
  339.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00, 3},
  340.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00, 3},
  341.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00, 3},
  342.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00, 3},
  343.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00, 3},
  344.             {03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,03,00,00,00,07,24,00, 3},
  345.             {03,00,00,00,07,00,00,00,03,00,00,00,07,00,00,00,03,00,00,00,00,00,00, 3},
  346.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,03,00,00,00,00,00,00, 3},
  347.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,13, 2,16,17,18,02,02,15},
  348.             {03,00,00,00,00,00,00,00,03,26,00,00,00,00,00,24,03,00,00,00,00,19,20, 3},
  349.             {10, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2,11}},
  350.             /*graveyard: level 4*/
  351.             {{9, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  352.             {03,34,34,34,34,34,34,36,38,34,36,34,34,34,34,34,36,34,34,34,36,39,34, 3},
  353.             {03,34,34,36,34,36,34,34,34,36,34,34,36,34,34,34,34,34,36,34,35,34,34, 3},
  354.             {03,36,34,34,34,36,34,34,34,34,34,34,34,34,36,36,34,34,34,34,34,36,34, 3},
  355.             {03,34,34,34,34,34,34,38,34,34,36,34,34,36,34,34,34,36,34,36,34,34,38, 3},
  356.             {03,34,34,36,34,34,36,36,34,34,34,36,36,34,34,34,36,34,35,34,36,34,34, 3},
  357.             {03,36,34,34,34,38,34,34,36,36,34,34,34,36,34,34,36,34,34,38,36,34,34, 3},
  358.             {03,34,06, 2, 8,36,34,34,34,34,35,34,36,34,34,36,34,34,36,34,34,34,36, 3},
  359.             {03,34,37,20,03,34,34,34,36,36,39,34,34,36,36,34,34,34,34,35,34,34,34, 3},
  360.             {03,34,06,02,11,36,34,36,34,34,36,34,34,36,34,34,36,36,34,36,34,34,34, 3},
  361.             {03,34,34,36,34,34,36,34,34,36,34,36,36,34,36,36,34,34,34,36,34,36,34, 3},
  362.             {03,34,36,34,34,34,34,34,34,36,34,34,34,34,34,34,34,36,35,34,34,36,34, 3},
  363.             {03,34,36,34,34,36,34,38,36,34,36,36,34,36,34,36,34,34,34,35,34,34,36, 3},
  364.             {03,34,34,36,34,34,36,34,34,34,34,34,36,34,35,34,34,36,36,34,34,36,34, 3},
  365.             {03,36,34,34,34,34,36,34,34,36,38,34,34,34,34,34,36,38,34,34,34,34,34, 3},
  366.             {10, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2,02, 2, 2, 2, 2, 2, 2,11}},
  367.             /*spiral: level 5*/
  368.             {{9, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  369.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  370.             {03,00,00,00,00,00,24,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  371.             {13,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02, 8,00,00, 3},
  372.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00, 3},
  373.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00, 3},
  374.             {03,00,00, 9,02,02,02,02,02,02,02,02,02,02,02,02,02, 8,00,00,07,00,00, 3},
  375.             {03,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,29,03,00,00,40,00,00, 3},
  376.             {03,00,00,03,00,00,00,00,00,00,00,00,00,00,00,06,02,15,00,00,05,00,00, 3},
  377.             {03,00,00,03,00,00,06,02,02,02,02,02,02, 8,42,19,20,03,00,00,03,00,00, 3},
  378.             {03,00,00,03,00,00,29,00,00,00,00,00,00,10,02,02,02,11,00,00,03,00,00, 3},
  379.             {03,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00, 3},
  380.             {03,00,00,10,02,02,02,04,40,06,02,02,02,04,40,06,02,02,02,02,11,00,00, 3},
  381.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  382.             {03,24,00,00,00,00,00,00,00,00,00,00,28,00,00,00,00,00,00,00,00,00,00, 3},
  383.             {10, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2,02, 2, 2, 2, 2, 2, 2,11}},
  384.             /*pool: level 6*/
  385.             {{9, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  386.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  387.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  388.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  389.             {13,02,02,02,02,02,02,02,02,02,02,04,42,06,02,02,02,02,02,02,02,02,02,15},
  390.             {30,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,31},
  391.             {13,02,04,42,06,02,02,12,02,02,02,02,02,02,02,02,02,02,02,02,04,42,06,15},
  392.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  393.             {03,00,00,00,00,00,00,07,00,00,00,00,00,00,00,00,00,00,05,00,00,00,00, 3},
  394.             {03,00,00,00,00,00,00,40,00,00,00,00,00,00,00,00,00,00,03,00,00,00,00, 3},
  395.             {03,00,00,00,00,00,00,05,00,00,00,00,00,00,00,00,00,00,03,00,00,00,00, 3},
  396.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,00,00,13,02,02,02,02,15},
  397.             {03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00,00,00,07,00,00,00,29, 3},
  398.             {03,00,00,00,00,00,00,03,00,06,02, 8,00,00,00,00,00,00,42,00,00,00,29, 3},
  399.             {03,24,00,00,00,00,29,03,00,19,20,03,00,00,00,00,00,28,05,00,00,00,29, 3},
  400.             {10, 2, 2, 2,02, 2, 2,14, 2, 2, 2,14,02, 2, 2, 2,02, 2,14, 2, 2, 2, 2,11}},
  401.             /*open: level 7*/
  402.             /*0,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23*/
  403.             {{9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  404.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  405.             {03,00,05,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,24, 6,02, 8,00, 3},
  406.             {03,00,13,04,00,00,00,00,00,00,29,00,00,00,00,00,00,00,00,00,00, 7,00, 3},
  407.             {03,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,29, 3},
  408.             {03,29,07,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,28,00,00,00, 3},
  409.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  410.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,05,27,00,00,00,00,00,00,00, 3},
  411.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00, 3},
  412.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,00,00, 3},
  413.             {03,00,00,00,00,06,02,02,04,00,00,00,00,00,07,29,00,00,00,00,00,00,00, 3},
  414.             {03,00,00,00,00,00,00,00,00,24,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  415.             {03,00,05,00,00,00,28,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  416.             {03,00,10,02,04,00,00,00,00,00,00,00,00,00,00,00,00,00, 9,16,17,18,02,15},
  417.             {03,00,00,00,29,00,00,00,00,00,00,00,00,00,00,00,00,00, 3,00,00,19,20, 3},
  418.             {10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2,11}},
  419.             /*pacmaze: level 8*/
  420.             {{9, 2, 2,12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 8},
  421.             {03,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,19,20,03},
  422.             {03,00,00,03,00, 9,02,02,04,00,06,12,04,00,06,02,02, 8,00,03,00,06,02,15},
  423.             {03,00,00,03,29,03,00,00,00,00,00,03,00,00,00,00,00,03,29,03,00,00,00,03},
  424.             {03,00,00,03,00,03,00,05,00,00,00,03,00,00,00,05,00,03,00,03,00,00,00,03},
  425.             {03,00,00,03,00,07,00,13,02,04,00,07,00,06,02,15,00,07,00,03,00,00,00,03},
  426.             {03,00,00,03,00,00,00,03,00,00,00,00,00,00,00,03,00,00,00,03,00,00,00,03},
  427.             {03,00,00,10,02,04,00,07,00, 9,04,00,06, 8,00,07,00,06,02,11,00,00,00,03},
  428.             {03,00,00,00,00,00,00,00,00,03,00,00,00,03,00,00,00,00,00,00,00,00,00,03},
  429.             {03,00,00, 9,02,04,00,05,00,10,02,02,02,11,00,05,00,06,02, 8,00,00,00,03},
  430.             {03,00,00,03,00,00,00,03,00,00,00,24,00,00,00,03,00,00,00,03,00,00,00,03},
  431.             {03,00,00,03,00,05,00,03,00,06,02,12,02,04,00,03,00,05,00,03,00,00,00,03},
  432.             {03,00,00,03,29,03,00,03,00,00,00,03,00,00,00,03,00,03,29,03,00,00,00,03},
  433.             {03,00,00,03,00,07,00,10,02,04,00,07,00,06,02,11,00,07,00,03,00,00,00,03},
  434.             {03,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00,00,03},
  435.             {10, 2, 2,14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2,11}},
  436.             /*lines: level 9*/
  437.             /*0,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23*/
  438.             {{9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8},
  439.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  440.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  441.             {13, 2, 2, 2, 4,42, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4,42, 6, 2,15},
  442.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,40,00,00,00,00,00,00,28, 3},
  443.             {13, 2, 2, 2, 2, 2, 2, 4,00, 6, 2, 2, 2, 2, 2, 4,00, 6, 2, 2, 2, 2, 2,15},
  444.             {03,24,00,00,00,42,00,00,00,00,00,00,00,40,00,00,00,00,00,00,00,00,27, 3},
  445.             {13, 2, 2, 2, 2, 4,00, 6, 2, 2, 2, 2, 2, 2, 4,40, 6, 2, 2, 2, 2, 2, 2,15},
  446.             {03,29,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26, 3},
  447.             {13, 2, 2, 4,00, 6, 2, 2, 2, 2, 2, 2, 4,00, 6, 2, 2, 2, 2, 4,00, 6, 2,15},
  448.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  449.             {13,16,17,18, 2, 2, 2, 2, 2, 2, 4,00, 6, 2, 2, 4,40, 6, 2, 2, 2, 2, 2,15},
  450.             {03,00,00,00,00,00,00,00,00,00,00,40,00,00,00,00,00,00,00,00,00,00,24, 3},
  451.             {13, 2, 2, 2, 4,00, 6, 2, 2, 2, 2, 2, 4,00, 6, 2, 2, 4,00, 6, 2, 2, 2,15},
  452.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,28,00,00,00,00,00,00,19,20, 3},
  453.             {10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,11}},
  454.             /*zigzag*/
  455.             /*0,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23*/
  456.             {{9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  457.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  458.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  459.             {13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2,04,00,00, 3},
  460.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  461.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,28, 3},
  462.             {03,00,00,06, 2, 2, 2, 2, 2, 2, 2, 2, 4,40, 6, 2,02, 2, 2, 4,40, 6, 2,15},
  463.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  464.             {03,24,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  465.             {13, 2, 2, 2, 2, 2, 2, 2, 2, 4,40, 6, 2, 2, 2, 2,02, 2, 2, 2,04,00,00, 3},
  466.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  467.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,29, 3},
  468.             {03,00,00,06, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2,14},
  469.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00},
  470.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 9},
  471.             {10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,11}},
  472.             /*hall*/
  473.             {{9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8},
  474.             {03,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,10},
  475.             {03,43,47,44,45,45,46,44,46,44,44,45,44,46,44,46,44,45,44,44,45,44,43,43},
  476.             {03,43,44,44,05,44,46,44,45,05,45,46,44,46,05,45,46,44,45,05,46,45,43, 9},
  477.             {03,43,46,44,03,44,46,28,44,03,44,44,45,44,03,44,45,46,44,03,44,44,43,03},
  478.             {03,43,44,45,07,46,44,45,46,07,46,45,44,44,07,44,44,44,46,07,46,28,43,03},
  479.             {03,43,44,45,44,46,44,45,46,45,46,44,46,44,45,44,45,44,46,44,46,45,43,03},
  480.             {03,43,46,44,45,45,46,44,44,44,44,46,44,46,44,46,44,45,44,44,45,44,43,03},
  481.             {03,43,44,45,44,46,44,44,45,46,46,46,44,45,44,45,44,46,44,46,46,45,43,03},
  482.             {03,43,46,44,45,45,46,45,46,44,44,45,44,46,44,46,44,45,46,44,45,44,43,03},
  483.             {03,43,44,45,05,44,46,44,45,05,45,46,45,46,05,45,44,45,44,05,44,46,43,03},
  484.             {03,43,44,45,03,46,44,45,46,03,44,46,46,44,03,44,46,44,46,03,46,44,43,03},
  485.             {11,43,46,44,07,45,46,44,46,07,44,45,44,46,07,46,44,45,44,07,45,44,43,03},
  486.             {43,43,44,45,44,46,44,45,46,45,46,44,46,44,45,44,45,44,46,44,46,45,43,03},
  487.             { 8,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,03},
  488.             {10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,11}},
  489.             /*batland*/
  490.             /*0,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23*/
  491.             {{9, 2, 2, 2,12, 2, 2, 2,12, 2, 2, 2,12, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 8},
  492.             {11,00,00,00,07,00,00,00,07,00,00,00,07,00,00,00,03,00,00,00,00,00,00, 3},
  493.             {00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,06,02, 8,00,00, 3},
  494.             { 8,00,00,00,05,00,00,00,05,00,00,00,05,00,00,00,03,00,19,20,03,00,00, 3},
  495.             {13,04,00,06,01,02,02,02,01,04,40,06,01,04,00,06,01,02,02,02,15,00,00, 3},
  496.             {03,00,00,00,03,00,00,00,07,00,00,00,07,00,00,00,07,00,00,00,03,00,00, 3},
  497.             {03,00,00,00,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03,00,00, 3},
  498.             {03,26,00,00,03,00,00,00,05,00,00,00,05,00,00,28,05,00,00,00,03,00,00, 3},
  499.             {13,04,40,06,01,04,00,06,01,04,00,06,01,04,40,06,01,04,00,06,15,00,00, 3},
  500.             {03,00,00,00,07,00,00,00,07,00,00,28,03,00,00,00,07,00,00,00,03,00,00, 3},
  501.             {03,00,00,00,00,00,00,00,40,00,00,00,03,00,00,00,00,00,00,00,03,00,00, 3},
  502.             {03,00,00,24,05,00,00,00,05,00,00,00,03,27,00,00,05,00,00,00,03,00,00, 3},
  503.             {13,02,02,02,14,16,17,18,14,02,02,02,14,02,02,02,14,02,02,02,11,00,00, 3},
  504.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, 3},
  505.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,32, 3},
  506.             {10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,11}},
  507.             /*ministone: level 13*/
  508.             {{9, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 2,02, 2, 2, 2, 2, 2, 2, 8},
  509.             {03,00,00,00,00,00,00,00,00,00,00,40,00,00,00,00,00,00,00,00,00,00,00, 3},
  510.             {03,00, 9, 2, 2, 2, 2, 2,04,00,06, 2, 2,04,00,06, 2, 2, 2, 2, 2, 8,00, 3},
  511.             {03,00,03,36,34,34,34,34,34,34,34,36,34,36,34,34,36,34,34,34,36,03,00, 3},
  512.             {03,00,03,34,34,34,34,36,34,34,36,34,34,36,34,34,34,34,36,34,34,03,00, 3},
  513.             {03,00,03,34,34,35,34,34,36,34,34,36,34,34,36,34,34,35,34,34,34,03,00, 3},
  514.             {03,00,03,36,34,34,36,34,34,36,34,34,35,34,34,36,36,34,36,34,34,03,00, 3},
  515.             {03,00,03,34,36,34,34,36,34,34,36,34,36,34,34,36,34,34,34,36,34,03,00, 3},
  516.             {03,00,03,34,34,34,34,36,34,36,34,34,36,38,36,34,36,34,34,34,34,03,00, 3},
  517.             {03,00,03,34,36,34,36,34,38,36,34,34,34,34,36,34,34,34,36,34,36,03,00, 3},
  518.             {03,00,03,34,34,34,36,34,36,34,36,34,34,35,34,34,34,34,36,34,36,03,00, 3},
  519.             {03,00,03,34,34,36,34,34,34,34,34,36,36,34,36,34,36,34,34,36,39,03,00, 3},
  520.             {03,00,03,36,34,34,36,34,34,36,34,34,34,38,34,34,36,34,36,34,34,03,00, 3},
  521.             {11,00,03,34,35,34,34,36,36,34,34,34,34,36,34,34,34,34,34,34,34,03,00,10},
  522.             {00,00,03,34,34,34,34,34,34,35,34,36,34,34,35,34,34,34,34,36,34,03,00,00},
  523.             {02, 2,14, 2,02, 2, 2, 2, 2,02, 2,02,02, 2,02, 2,02, 2, 2, 2, 2,14, 2,02}},
  524.             /*more rooms: level 14*/
  525.             {{9, 2, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2,12, 2, 2, 2, 2, 2, 2, 2, 8},
  526.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,19,20,03},
  527.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,06,02,15},
  528.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,03},
  529.             {03,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,00,03},
  530.             {13,02,02,04,00,06, 2,02,14,02,16,17,18,02,02,14,02,02,16,17,18,02,02,15},
  531.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,26,00,00,03},
  532.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  533.             {03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  534.             {03,00,00,00,00,00,26,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,03},
  535.             {13,02,02,02,02,02,16,17,18,12,02,02,04,00,06,02,12,02,02,04,00,06,02,15},
  536.             {03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  537.             {03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  538.             {03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  539.             {03,00,00,00,00,00,00,00,00,03,00,00,00,00,00,00,03,00,00,00,00,00,00,03},
  540.             {10, 2, 2, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2,14, 2, 2, 2, 2, 2, 2,11}},
  541.             };
  542. Boolean        occuval[64]={
  543.                 0,1,1,1,1,1,1,1,
  544.                 1,1,1,1,1,1,1,1,
  545.                 1,1,1,0,0,1,1,0,
  546.                 0,0,0,0,1,1,1,1,
  547.                 0,0,0,1,1,0,0,0,
  548.                 1,0};
  549.                 
  550. char        data[MAXLEVELS][MAXOBJECTS][8]={
  551.         {    {0,0,0,0,0}        },            /*level 0*/
  552.         {    {APPLE,0,5,13,1,0,0,0},        /*level 1*/
  553.             {KEY,0,8,1,1,0,0,1},
  554.             {KEYHOLE,0,4,9,1,0,0,1},
  555.             {GATE,0,1,10,1},
  556.             {TREASURE,0,17,11,1},
  557.             {BUGGLES,0,22,14,2,0,0,0},
  558.             {BUGGLES,0,12,12,2,0,0,0}},
  559.         {    {APPLE,0,17,2,1,0,0,0},        /*level 2*/
  560.             {SUPERAPPLE,0,6,14,1,0,0,0},
  561.             {KEY,0,14,1,1,0,0,2},
  562.             {KEYHOLE,0,6,9,1,0,0,2},
  563.             {GATE,0,7,10,1},
  564.             {MACHINE,0,12,14,1,0,95},    /*last # is speed*/
  565.             {TREASURE,0,7,14,1,0,10},
  566.             {BUGGLES,0,21,12,2,0,0,0},
  567.             {BUGGLES,0,8,12,2,0,0,0}},
  568.         {    {APPLE,0,15,14,1,0,0,0},    /*level 3*/
  569.             {APPLE,0,21,10,1,0,0,0},
  570.             {MACHINE,0,11,1,1,0,75,0},
  571.             {EGGLES,0,1,11,2,0,0,0},
  572.             {EGGLES,4,2,12,2,0,0,0},
  573.             {EGGLES,2,1,13,2,0,0,0},
  574.             {EGGLES,2,15,10,2,0,0,0},
  575.             {BUGGLES,0,19,6,2,0,0,0},
  576.             {BUGGLES,0,22,6,2,0,0,0},
  577.             {KEY,0,22,1,1,0,0,2},
  578.             {KEYHOLE,0,9,14,1,0,0,2},
  579.             {GATE,0,18,13,1},
  580.             {TREASURE,0,17,04,1},
  581.             {TREASURE,0,21,04,1}},
  582.         {    {BAT,0,11,10,2,0,-10,-10},    /*graveyard:level 4*/
  583.             {BAT,0,11,10,2,0,32,10},
  584.             /*{GHOST,0,16,10,2,0,0,0},*/
  585.             {TREASURE,0,21,1,1,34,10},
  586.             {TREASURE,0,10,8,1,34,10},
  587.             {BAT,0,16,12,2,0,14,-10}},
  588.         {    {APPLE,0,6,2,1,0,0,0},        /*spiral:level 5*/
  589.             {APPLE,0,1,14,1,0,0,0},
  590.             {BUGGLES,0,18,2,2,0,0,0},
  591.             {BUGGLES,0,22,5,2,0,0,0},
  592.             {BAT,0,11,10,2,0,26,10},
  593.             {TREASURE,0,6,10,1},
  594.             {TREASURE,0,16,7,1,0,10},
  595.             {MACHINE,0,12,14,1,0,50,0}},
  596.         {    {APPLE,0,1,14,1,0,0,0},        /*pool:level 6*/
  597.             {BUGGLES,0,18,2,2,0,0,0},
  598.             {BUGGLES,0,3,3,2,0,0,0},
  599.             {POOLBALL,1,22,5,2,0,0,0},
  600.             {BAT,0,11,10,2,0,26,10},
  601.             {EGGLES,2,21,13,2,0,0,0},
  602.             {TREASURE,0,22,12,1,0,10},
  603.             {TREASURE,0,22,13,1,0,15},
  604.             {TREASURE,0,22,14,1},
  605.             {TREASURE,0,6,14,1},
  606.             {INLETL,0,0,5,1},
  607.             {INLETR,0,23,5,1},
  608.             {MACHINE,0,17,14,1,0,45,0}},
  609.         {    {APPLE,0,18,2,1,0,0,0},        /*open:level 7*/
  610.             {APPLE,0, 9,11,1,0,0,0},
  611.             {EGGLES,2,12,10,2,0,0,0},
  612.             {EGGLES,2,13,11,2,0,0,0},
  613.             {EGGLES,2,5,7,2,0,0,0},
  614.             {EGGLES,2,1,14,2,0,0,0},
  615.             {TREASURE,0,1,5,1,0,5},
  616.             {TREASURE,0,4,14,1,0,18},
  617.             {TREASURE,0,22,4,1,0,10},
  618.             {TREASURE,0,10,3,1},
  619.             {TREASURE,0,15,10,1},
  620.             {KEY,0,15,7,1,0,0,2},
  621.             {KEYHOLE,0,3,2,1,0,0,2},
  622.             {GATE,0,19,13,1},
  623.             {MACHINE,0,6,12,1,0,50,0},
  624.             {MACHINE,0,19,5,1,0,40,0}},
  625.         {    {APPLE,0,11,10,1,0,0,0},    /*pacmaze:level 8*/
  626.             {GHOST,0,20,8,2,0,0,0},
  627.             {GHOST,0,10,0,2,10,0,0},
  628.             {TREASURE,0,4,3,1,0,10},
  629.             {TREASURE,0,4,12,1,0,10},
  630.             {TREASURE,0,18,3,1,0,15},
  631.             {TREASURE,0,18,12,1,0,10},
  632.             {BAT,0,12,12,2,0,-20,-10}},
  633.         {    {MACHINE,0,22,4,1,0,40,0},    /*lines:level 9*/
  634.             {MACHINE,0,14,14,1,0,45,0},
  635.             {BUGGLES,0,3,9,2,0,0,0},
  636.             {KEY,0,22,6,1,0,0,1},
  637.             {KEYHOLE,0,22,8,1,0,0,1},
  638.             {TREASURE,0,1,8,1,0,10},
  639.             {APPLE,0,1,6,1,0,0},
  640.             {APPLE,0,22,12,1,0,0},
  641.             {GATE,0,1,11,1}},
  642.         {    {MACHINE,0,22,5,1,0,40,0},    /*zigzag:level 10*/
  643.             {BAT,0,24,11,2,0,-2,10},
  644.             {BUGGLES,1,20,2,2,0,0,0},
  645.             {BUGGLES,0,7,14,2,0,0,0},
  646.             {BEHOLD,0,8,12,2,0,0,0},
  647.             {TREASURE,0,22,11,1,0,10},
  648.             {APPLE,0,1,8,1,0,0}},
  649.         {    {MACHINE,0,21,5,1,0,40,0},    /*great hall:level 11*/
  650.             {MACHINE,0,7,4,1,0,40,0},
  651.             {BUGGLES,3,3,3,2,0,0,0},
  652.             {BUGGLES,3,10,10,2,0,0,0},
  653.             {RING,0,2,2,1,0,0,1},
  654.             {BEHOLD,0,8,12,2,0,0,0}},
  655.         {    {BAT,0,3,14,2,0,-3,2},    /*batland:level 12*/
  656.             {KEY,0,13,11,1,0,0,1},
  657.             {KEYHOLE,0,1,7,1,0,0,1},
  658.             {GATE,0,5,12,1},
  659.             {APPLE,0,3,11,1,0,0},
  660.             {SUPERAPPLE,0,22,14,1,0,0,0},
  661.             {MACHINE,0,15,7,1,0,35,0},
  662.             {MACHINE,0,11,9,1,0,30,0}},
  663.         {    {BAT,0,15,3,2,0,-10,-10},    /*ministone:level 13*/
  664.             {BAT,0,11,10,2,0,32,10},
  665.             {GHOST,0,4,10,2,0,0,0},
  666.             {TREASURE,0,20,11,1,34,19},
  667.             {BAT,0,20,12,2,0,14,-10}},
  668.         {    {BAT,0,15,3,2,0,-10,-10},    /*more rooms:level 14*/
  669.             {BAT,0,20,12,2,0,14,-10}}
  670.             };    /*status,dir,x,y,0 or 1 or 2,picture,alt1,alt2*/
  671.             
  672. Byte        upx[MAXLEVELS]={0,21,21,21,2,15,9,21,
  673.                             21,21,23,23,18,23};
  674. Byte        upy[MAXLEVELS]={0,1,14,14,8,9,14,14,
  675.                             1,14,13,2,3,14};
  676. Byte        startx[MAXLEVELS]={1,1,1,1,1,1,1,1,
  677.                                 1,1,1,0,0,0,1};
  678. Byte        starty[MAXLEVELS]={1,1,1,1,1,1,1,1,
  679.                                 1,1,1,13,2,14,8};
  680.             
  681. int            dir12x[9]={12,-12,0,0,12,-12,-12,12,0};
  682. int            dir12y[9]={0,0,-12,12,-12,-12,12,12,0};
  683. int            dir2x[9]={2,-2,0,0,2,-2,-2,2,0};
  684. int            dir2y[9]={0,0,-2,2,-2,-2,2,2,0};
  685. int            dir1x[9]={1,-1,0,0,1,-1,-1,1,0};
  686. int            dir1y[9]={0,0,-1,1,-1,-1,1,1,0};
  687. int            rebound[9]={1,0,3,2,6,7,4,5,9};
  688. int            diricex[8]={2,1,0,-1,-2,-1,0,1};
  689. int            diricey[8]={0,1,2,1,0,-1,-2,-1};
  690. int            undu[4]={1,0,-1,0};
  691. int            bounce[16]={-2,-4,-6,-7,-6,-4,-2,0,0};
  692.  
  693. int            plwalkpic[8][10]={
  694.                 {00, 1, 2, 3, 4, 5, 6, 7, 8 ,9},
  695.                 {16,17,18,19,20,21,22,23,24,25},
  696.                 {26,27,28,27,26,29,30,31,30,29},
  697.                 {10,11,12,11,10,13,14,15,14,13},
  698.                 {00, 1, 2, 3, 4, 5, 6, 7, 8 ,9},
  699.                 {16,17,18,19,20,21,22,23,24,25},
  700.                 {16,17,18,19,20,21,22,23,24,25},
  701.                 {00, 1, 2, 3, 4, 5, 6, 7, 8 ,9}
  702.                 };
  703.  
  704. int        batpic[16]={32,33,34,35,36,37,38,39,48,49,50,51,52,53,54,55};
  705. int        deadbatpic[8]={32,192,193,193,208,208,209,47};
  706. int        scorerollpic[24]={16,16,16,16,16,16,17,18,19,20,
  707.                     21,22,23,24,25,26,27,28,29,30,31,15,15,15};
  708. int        ghostpic[8]={40,41,42,43,44,43,42,41};
  709. int        poolballpic[2][16]={
  710.                 {32,33,34,35,36,37,38,39,32,32,32,32,32,32,32,32},
  711.                 {39,38,37,36,35,34,33,32,32,32,32,32,32,32,32,32}};
  712. int        bugglewalkpic[8][6]={
  713.                 {0,1,2,3,2,1},
  714.                 {4,5,6,7,6,5},
  715.                 {0,1,2,3,2,1},
  716.                 {0,1,2,3,2,1},
  717.                 {0,1,2,3,2,1},
  718.                 {4,5,6,7,6,5},
  719.                 {4,5,6,7,6,5},
  720.                 {0,1,2,3,2,1}
  721.                 };
  722. int        egglewalkpic[8][4]={
  723.                 {205,205,204,204},
  724.                 {221,221,220,220},
  725.                 {205,205,204,204},
  726.                 {205,205,204,204},
  727.                 {205,205,204,204},
  728.                 {221,221,220,220},
  729.                 {221,221,220,220},
  730.                 {205,205,204,204}};
  731. int        beholdpic[8]={51,52,52,53,53,52,52,51};
  732. int        missilepic[8]={40,41,42,43,56,57,58,59};
  733. int        arrowexplodepic[5]={44,45,60,61,62};
  734. int        gitempic[5]={226,227,227,227,227+16};
  735.  
  736. struct    finalbox    finals[MAXFINALS];
  737. struct    monsterdata    monster[MAXMONSTERS];
  738. struct    objectdata    object[MAXOBJECTS];
  739. struct    missiledata    missile[MAXMISSILES];
  740.  
  741.  
  742. /***Prototypes***/
  743. Boolean        IsColor();
  744. Boolean        IsIdle();
  745. Boolean        ispressed(unsigned short k);
  746. Boolean        ispressed2(unsigned short k);
  747. Rect        multrect(register int x,register int y);
  748. Rect        minimultrect(int x,int y);
  749. Rect        coorrect(register int x,register int y,register int size);
  750. Rect        coorrectl(int x,int y,int size);
  751. BitMap        makebitmap();
  752. void        cango(int *x,int *y,int xmod,int ymod,int direction,int size);
  753. void        cango2(int *x,int *y,int xmod,int ymod,int direction,int size);
  754. Boolean        occupied(int x,int y);
  755. void        doobject(struct objectdata *);
  756. void        doobject2(struct objectdata *);
  757. void        domonster(struct monsterdata *);
  758. void        domissile(struct missiledata *);
  759. short        keydir();
  760. Boolean        within(int x,int y,int x2,int y2,int size, int size2);
  761. int        getdir(int x,int y);
  762. int        getdir2(int x,int y);
  763.  
  764. pascal Boolean helpfilter(DialogPtr,EventRecord *,short *);
  765. pascal void pictproc(WindowPtr theDlg,short theItem );
  766.  
  767. pascal void okitemproc(WindowPtr theDlg,short theItem );
  768. pascal Boolean diafilter(DialogPtr,EventRecord *,short *);
  769.  
  770.  
  771.  
  772.  
  773. /*** Main ***/
  774. main()
  775. {
  776.     FrozenInit();
  777.     MiscInit();
  778.     MainLoop();
  779.     cleanup();
  780. }
  781. /**FrozenInit**/
  782. /*this is all the start up stuff that is done only once*/
  783. FrozenInit()
  784. {
  785.     ToolBoxInit();
  786.     WindowInit();
  787.     SetUpDragRect();
  788.     MenuBarInit();
  789. }
  790.  
  791.  
  792. /*** MainLoop ***/
  793. /*this is where we hang out when nobody is playing*/
  794. MainLoop()
  795. {
  796.     masterstatus=STATUS_WAIT;
  797.     landscape(0);
  798.     offtoon();
  799.     
  800.     while(masterstatus)
  801.     {
  802.         HandleEvent();
  803.         maintaincursor(gTheEvent.where);
  804.         switch(masterstatus)
  805.         {
  806.             case STATUS_WAIT:
  807.                 level=0;
  808.                 break;
  809.             case STATUS_GAME:
  810.                 Game();
  811.                 break;
  812.             case STATUS_NEWGAME:
  813.                 masterstatus=STATUS_GAME;
  814.                 break;
  815.             case STATUS_OVER:
  816.                 Over();
  817.                 break;
  818.             default:
  819.                 break;
  820.         }
  821.     }
  822. }
  823.  
  824.  
  825. /****Game****/
  826. Game()
  827. {
  828.     long    oldticks;
  829.     int    timetest;
  830.  
  831.     oldticks=gcounter=0;
  832.     sounder(gsndchannelc,tocattahandle);
  833.     score=0;
  834.     gbonuselg=FALSE;
  835.     health=healtht=80;
  836.     gnumitems=0;
  837.     drawsidepanel();
  838.     displayscore();
  839.     drawhealth();
  840.     displayitems();
  841.     level=startlevel;
  842.     setlevel(level);
  843.     occumaster=0;
  844.     EnableItem(gFileMenu,ABORT_ITEM);
  845.     EnableItem(gMiscMenu,PAUSE_ITEM);
  846.     
  847.     while (masterstatus==STATUS_GAME)
  848.     {
  849.         HandleEvent();
  850.         if(TickCount()<oldticks+2) timetest++;
  851.         else timetest=0;
  852.         while(TickCount()<oldticks+2)    /*should be 2*/
  853.             if (timetest>80)
  854.             {
  855.                 timetest=0;
  856.                 addmoremon=TRUE;
  857.             }
  858.         oldticks=TickCount();
  859.         testscroll();
  860.         
  861.         if (landscaperequest) landscape(level);    
  862.         
  863.         objects();
  864.         monsters();
  865.         missiles();
  866.         player();
  867.         objects2();
  868.         displayhealth();
  869.  
  870.         if (landscaperequest)
  871.         {
  872.             offtoon();
  873.             landscaperequest=FALSE;
  874.         }
  875.         finaldraw();
  876.         if (plx==upx[level]*32 && ply==upy[level]*32)
  877.             uplevel();
  878.         gcounter++;
  879.         if (!(gcounter&63)) healtht--;
  880.         gred=(gcounter&8);    /*change color every 16 counts*/
  881.  
  882.     }
  883.     DisableItem(gFileMenu,ABORT_ITEM);
  884.     DisableItem(gMiscMenu,PAUSE_ITEM);
  885. }
  886. /**uplevel**/
  887. uplevel()
  888. {
  889.     Str31    mystring;
  890.     
  891.     level++;
  892.     setlevel(level);
  893.     if(((hlevel+1)==level) && level<8)
  894.     {
  895.         hlevel++;
  896.         NumToString(hlevel,mystring);
  897.         if((level-1)==CountMItems(gStartMenu))
  898.             AppendMenu(gStartMenu,mystring);
  899.     }
  900. }
  901. /****Over****/
  902. Over()
  903. {
  904.     long    oldticks;
  905.     int    timetest;
  906.     Rect    fromrect,torect;
  907.  
  908.     oldticks=0;
  909.     gbonuselg=FALSE;
  910.     pls=5;    /*set player to cloud*/
  911.     /*drawhealth();
  912.     displayitems();*/
  913.     occumaster=0;
  914.     /*DisableItem(gFileMenu,ABORT_ITEM);*/
  915.     
  916.     fromrect=multrect(58%8,58/8);
  917.     torect=coorrect(width/2-80,height/2-10,32);
  918.     fromrect.right+=128;
  919.     torect.right+=128;
  920.     CopyMask ((BitMapPtr)&(**pix3),&(bitmask3),&(*myWindow).portBits,
  921.             &fromrect,&fromrect,&torect);
  922.             
  923.     while (masterstatus==STATUS_OVER)
  924.     {
  925.         HandleEvent();
  926.         if(TickCount()<oldticks+2) timetest++;
  927.         else timetest=0;
  928.         while(TickCount()<oldticks+2)    /*should be 2*/
  929.             if (timetest>80)
  930.             {
  931.                 timetest=0;
  932.                 addmoremon=TRUE;
  933.             }
  934.         oldticks=TickCount();
  935.         testscroll();
  936.         if (landscaperequest) landscape(level);
  937.         
  938.         objects();
  939.         monsters();
  940.         missiles();
  941.         player();
  942.         objects2();
  943.         if(colororbw) SetPort((GrafPtr)myCGrafPtr);
  944.         else SetPort(myGrafPtr);
  945.         drawgameover();
  946.         SetPort(myWindow);
  947.         
  948.         if (landscaperequest)
  949.         {
  950.             offtoon();
  951.             landscaperequest=FALSE;
  952.         }
  953.         finaldraw();
  954.         gcounter++;
  955.     }
  956. }
  957. /**drawgameover**/
  958. drawgameover()
  959. {
  960.     Rect    fromrect,torect;
  961.     
  962.     fromrect=multrect(58%8,58/8);
  963.     torect=coorrect(width/2-80,height/2-10,32);
  964.     fromrect.right+=128;
  965.     torect.right+=128;
  966.     
  967.     if(colororbw)    
  968.         CopyMask ((BitMapPtr)&(**pix3),&(bitmask3),(BitMapPtr)&myCGrafPtr->portPixMap,
  969.             &fromrect,&fromrect,&torect);
  970.     else
  971.         CopyMask (&bit3,&(bitmask3),&myGrafPtr->portBits,
  972.             &fromrect,&fromrect,&torect);
  973. }
  974.  
  975.  
  976.  
  977. /*** HandleEvent ***/
  978.  
  979. HandleEvent()
  980. {
  981.     char    theChar;
  982.     
  983.     WaitNextEvent(everyEvent,&gTheEvent,MIN_SLEEP,mousergn);
  984.     switch(gTheEvent.what)
  985.     {
  986.         case mouseDown:
  987.             HandleMouseDown();
  988.             break;
  989.         case keyDown:
  990.         case autoKey:
  991.             theChar=gTheEvent.message&charCodeMask;
  992.             /*gtheChar=theChar;*/
  993.             if((gTheEvent.modifiers&cmdKey)!=0)
  994.                 HandleMenuChoice(MenuKey(theChar));
  995.             break;
  996.         case keyUp:
  997.             /*gtheChar=0;*/
  998.             break;
  999.         case updateEvt:
  1000.             if ((WindowPtr)gTheEvent.message==myWindow)
  1001.             {
  1002.                 BeginUpdate((WindowPtr)gTheEvent.message);
  1003.                 landscaperequest=TRUE;
  1004.                 drawsidepanel();
  1005.                 if (masterstatus==STATUS_WAIT) offtoon();
  1006.                 EndUpdate((WindowPtr)gTheEvent.message);
  1007.             }
  1008.             break;
  1009.         case app4Evt:
  1010.             if(gTheEvent.message&0x01000000)    /*suspend or resume*/
  1011.             {
  1012.                 if(gTheEvent.message&0x00000001)
  1013.                 {
  1014.                     /*resume events*/
  1015.                 }
  1016.                 else
  1017.                 {
  1018.                     /*suspend event*/
  1019.                 }
  1020.             }
  1021.             if((gTheEvent.message&0xff000000)==0xfa000000)
  1022.                 maintaincursor(gTheEvent.where);
  1023.     }
  1024.     // if(gCallBackPerformed) disposea();
  1025. }
  1026.  
  1027. /*** HandleMouseDown ***/
  1028. HandleMouseDown()
  1029. {
  1030.     WindowPtr    whichWindow;
  1031.     int            thePart;
  1032.     long int    menuChoice,windSize;
  1033.     Point        p;
  1034.     
  1035.     thePart=FindWindow(gTheEvent.where,&whichWindow);
  1036.     switch(thePart)
  1037.     {
  1038.         case inMenuBar:
  1039.             menuChoice=MenuSelect(gTheEvent.where);
  1040.             HandleMenuChoice(menuChoice);
  1041.             break;
  1042.         case inSysWindow:
  1043.             SystemClick(&gTheEvent,whichWindow);
  1044.             break;
  1045.         case inDrag:
  1046.             DragWindow(whichWindow,gTheEvent.where,&gDragRect);
  1047.             setmousergn();
  1048.             break;
  1049.         case inGoAway:
  1050.             DisposeWindow(whichWindow);
  1051.             break;
  1052.         case inContent:
  1053.             p=gTheEvent.where;
  1054.             GlobalToLocal(&p);
  1055.             DoContent(p);
  1056.             break;
  1057.     }
  1058. }
  1059. /*** DoContent ***/
  1060. DoContent(p)
  1061. Point    p;
  1062. {
  1063.     int    loop;
  1064.     long    dummy;
  1065.     
  1066.     for(loop=0;loop<NUM_OF_BUTTONS;loop++)
  1067.     {
  1068.         if (PtInRect(p,&gbuttonrect[loop]))
  1069.         {
  1070.             DrawPicture(gbuttonpicd[loop],&gbuttonrect[loop]);
  1071.             while (Button() && PtInRect(p,&gbuttonrect[loop]))
  1072.             {
  1073.                 WaitNextEvent(everyEvent,&gTheEvent,MIN_SLEEP,NIL_MOUSE_REGION);
  1074.                 p=gTheEvent.where;
  1075.                 GlobalToLocal(&p);
  1076.                 
  1077.             }
  1078.             /*Delay(2,&dummy);*/
  1079.             /*check if user lifts button in orig rect*/
  1080.             if (PtInRect(p,&gbuttonrect[loop]))
  1081.             {
  1082.                 switch (loop)
  1083.                 {
  1084.                     case 0:    /*play*/
  1085.                         masterstatus=STATUS_NEWGAME;
  1086.                         break;
  1087.                     case 1:    /*pause*/
  1088.                         pause();
  1089.                         break;
  1090.                     case 2:    /*quit*/
  1091.                         quitdialog();
  1092.                         if(masterstatus==STATUS_QUIT)
  1093.                         {
  1094.                             level=0;
  1095.                             soundkill();
  1096.                         }
  1097.                         break;
  1098.                     case 3:    /*help*/
  1099.                         helpdialog();
  1100.                         break;
  1101.                 }
  1102.             }
  1103.             DrawPicture(gbuttonpicu[loop],&gbuttonrect[loop]);
  1104.         }
  1105.     }
  1106. }
  1107.  
  1108.  
  1109. /*** HandleMenuChoice ***/
  1110. HandleMenuChoice(menuChoice)
  1111. long int    menuChoice;
  1112. {
  1113.     int    theMenu,theItem;
  1114.     
  1115.     if(menuChoice!=0)
  1116.     {
  1117.         theMenu=HiWord(menuChoice);
  1118.         theItem=LoWord(menuChoice);
  1119.         switch(theMenu)
  1120.         {
  1121.             case APPLE_MENU_ID:
  1122.                 HandleAppleChoice(theItem);
  1123.                 break;
  1124.             case FILE_MENU_ID:
  1125.                 HandleFileChoice(theItem);
  1126.                 break;
  1127.             case OPTIONS_MENU_ID:
  1128.                 HandleOptionsChoice(theItem);
  1129.                 break;
  1130.             case SIZE_MENU_ID:
  1131.                 HandleSizeChoice(theItem);
  1132.                 break;
  1133.             case MISC_MENU_ID:
  1134.                 HandleMiscChoice(theItem);
  1135.                 break;
  1136.             case START_MENU_ID:
  1137.                 HandleStartChoice(theItem);
  1138.                 break;
  1139.             case CONTROL_MENU_ID:
  1140.                 HandleControlChoice(theItem);
  1141.                 break;
  1142.         }
  1143.         HiliteMenu(0);
  1144.     }
  1145. }
  1146.  
  1147.  
  1148. /*** HandleAppleChoice ***/
  1149.  
  1150. HandleAppleChoice(theItem)
  1151. int    theItem;
  1152. {
  1153.     Str255    accName;
  1154.     int        accNumber;
  1155.     int        itemNumber;
  1156.     DialogPtr    AboutDialog;
  1157.     
  1158.     switch(theItem)
  1159.     {
  1160.         case ABOUT_ITEM:
  1161.             /*NoteAlert(ABOUT_ALERT,NIL_POINTER);*/
  1162.             helpdialog();
  1163.             break;
  1164.         default:
  1165.             GetItem(gAppleMenu,theItem,accName);
  1166.             accNumber=OpenDeskAcc(accName);
  1167.             break;
  1168.     }
  1169. }
  1170.  
  1171. /*** HandleFileChoice ***/
  1172. HandleFileChoice(theItem)
  1173. int    theItem;
  1174. {
  1175.     switch(theItem)
  1176.     {
  1177.         case ABORT_ITEM:
  1178.             masterstatus=STATUS_OVER;
  1179.             /*level=0;*/
  1180.             break;
  1181.         case QUIT_ITEM:
  1182.             quitdialog();
  1183.             break;
  1184.         case NEW_ITEM:
  1185.             masterstatus=STATUS_NEWGAME;
  1186.             break;
  1187.     }
  1188. }
  1189.  
  1190. /*** HandleOptionsChoice ***/
  1191. HandleOptionsChoice(theItem)
  1192. int    theItem;
  1193. {
  1194.     switch(theItem)
  1195.     {
  1196.         case SOUND_ITEM:
  1197.             if(soundison)
  1198.             {
  1199.                 CheckItem(gOptionsMenu,SOUND_ITEM,FALSE);
  1200.                 soundison=FALSE;
  1201.                 soundkill();
  1202.                 break;
  1203.             }
  1204.             else
  1205.             {
  1206.                 CheckItem(gOptionsMenu,SOUND_ITEM,TRUE);
  1207.                 soundison=TRUE;
  1208.                 break;
  1209.             }
  1210.     }
  1211. }
  1212. soundkill()
  1213. {
  1214.     SndCommand        mycommand;
  1215.  
  1216.     mycommand.cmd=quietCmd;
  1217.     if(gsndchannela==NIL) return;
  1218.     if(SndDoImmediate(gsndchannela,&mycommand))
  1219.         DoAlert("\pError in snd channel cmd");
  1220. }
  1221.  
  1222. /*** HandleSizeChoice***/
  1223. HandleSizeChoice(theItem)
  1224. int    theItem;
  1225. {
  1226.     int    loop;
  1227.     
  1228.     switch(theItem)
  1229.     {
  1230.         case NATURAL_ITEM:
  1231.             lwidth=natlwidth;
  1232.             lheight=natlheight;
  1233.             break;
  1234.         case THE10BY10_ITEM:
  1235.             lwidth=10;
  1236.             lheight=10;
  1237.             break;
  1238.         case THE12BY12_ITEM:
  1239.             lwidth=12;
  1240.             lheight=12;
  1241.             break;
  1242.         case THE14BY13_ITEM:
  1243.             lwidth=14;
  1244.             lheight=13;
  1245.             break;
  1246.  
  1247.     }
  1248.     CheckItem(gSizeMenu,sizecheck,FALSE);
  1249.     CheckItem(gSizeMenu,theItem,TRUE);
  1250.     sizecheck=theItem;
  1251.     sizeset();
  1252.     if (lmapx>MAXLWIDTH-lwidth) lmapx=MAXLWIDTH-lwidth;
  1253.     mapx=lmapx*32;
  1254.     if (lmapy>MAXLHEIGHT-lheight) lmapy=MAXLHEIGHT-lheight;
  1255.     mapy=lmapy*32;
  1256.     SizeWindow(myWindow,width+192,height,TRUE);
  1257.     for (loop=0;loop<NUM_OF_BUTTONS;loop++)
  1258.     {
  1259.         gbuttonrect[loop].left=width+32+loop*32;
  1260.         gbuttonrect[loop].top=256;
  1261.         gbuttonrect[loop].right=width+64+loop*32;
  1262.         gbuttonrect[loop].bottom=256+32;
  1263.     }
  1264.     setmousergn();
  1265.     landscaperequest=TRUE;
  1266.     drawsidepanel();
  1267. }
  1268. /*** HandleStartChoice***/
  1269. HandleStartChoice(theItem)
  1270. int    theItem;
  1271. {
  1272.     CheckItem(gStartMenu,startlevel,FALSE);
  1273.     CheckItem(gStartMenu,theItem,TRUE);
  1274.     startlevel=theItem;
  1275. }
  1276. /*** HandleControlChoice***/
  1277. HandleControlChoice(theItem)
  1278. int    theItem;
  1279. {
  1280.     if(theItem==1)    /*keyboard*/
  1281.     {
  1282.         CheckItem(gControlMenu,1,TRUE);
  1283.         CheckItem(gControlMenu,2,FALSE);
  1284.         gkeyormouse=FALSE;
  1285.     }
  1286.     if(theItem==2)    /*mouse*/
  1287.     {
  1288.         CheckItem(gControlMenu,2,TRUE);
  1289.         CheckItem(gControlMenu,1,FALSE);
  1290.         gkeyormouse=TRUE;
  1291.     }
  1292.     maintaincursor(gTheEvent.where);
  1293. }
  1294. /*** HandleMiscChoice ***/
  1295. HandleMiscChoice(theItem)
  1296. int    theItem;
  1297. {
  1298.     switch(theItem)
  1299.     {
  1300.         case PAUSE_ITEM:
  1301.             pause();
  1302.             break;
  1303.         case INSTRUCT_ITEM:
  1304.             helpdialog();
  1305.             break;
  1306.     }
  1307. }
  1308. /**pause**/
  1309. pause()
  1310. {
  1311.     long    dummy;
  1312.     
  1313.     if(masterstatus!=STATUS_GAME) return;
  1314.     ObscureCursor();
  1315.     soundkill();
  1316.     ontooff();
  1317.     TextFont(1);
  1318.     TextSize(64);
  1319.     TextMode(srcOr);
  1320.     MoveTo(width/2-80,height/2+20);
  1321.     Delay(20,&dummy);
  1322.     WaitNextEvent(everyEvent,&gTheEvent,6,mousergn);
  1323.     while (gTheEvent.what!=mouseDown&&gTheEvent.what!=keyDown)
  1324.     {
  1325.         WaitNextEvent(everyEvent,&gTheEvent,6,mousergn);
  1326.         ObscureCursor();
  1327.         if (TickCount()&0x00000020) 
  1328.         {
  1329.             MoveTo(width/2-80,height/2+20);
  1330.             ForeColor(greenColor);
  1331.             if(level==11)
  1332.                 ForeColor(yellowColor);
  1333.             DrawString("\pPause");
  1334.             ForeColor(blackColor);
  1335.         }
  1336.         else offtoon();
  1337.         
  1338.     }
  1339.     landscaperequest=TRUE;
  1340.     offtoon();
  1341.     ForeColor(blackColor);
  1342. }
  1343.  
  1344.  
  1345.  
  1346. /***maintaincursor***/
  1347. /*checks positions of cursor and makes appropriate changes
  1348. according to position*/
  1349. maintaincursor(mypoint)
  1350. Point    mypoint;
  1351. {
  1352.     if (PtInRect(mypoint,&trueplayrect)&&gkeyormouse)
  1353.         SetCursor(*gtargetcursor);
  1354. }
  1355.  
  1356.  
  1357. /**** Initialization subroutines ****/
  1358. /*** ToolBoxInit ***/
  1359. ToolBoxInit()
  1360. {
  1361.     InitGraf(&qd.thePort);
  1362.     InitFonts();
  1363.     FlushEvents(everyEvent,    REMOVE_ALL_EVENTS);
  1364.     InitWindows();
  1365.     InitMenus();
  1366.     TEInit();
  1367.     InitDialogs(NIL_POINTER);
  1368.     InitCursor();
  1369. }
  1370.  
  1371. /*** WindowInit ***/
  1372. WindowInit()
  1373. {
  1374.     if (IsColor())
  1375.     {
  1376.         colororbw=TRUE;
  1377.         gbasepic=500;
  1378.         openpixmaps();
  1379.     }
  1380.     else
  1381.     {
  1382.         colororbw=FALSE;
  1383.         gbasepic=600;
  1384.         openbitmaps();
  1385.     }
  1386. }
  1387. /**openpixmaps**/
  1388. openpixmaps()
  1389. {    
  1390.     Point            tempP;
  1391.     Rect            r;
  1392.     CTabHandle        ourCMHandle;
  1393.     Handle            dumbhandle;
  1394.     PaletteHandle    mypalettehandle;
  1395.     long            offRowBytes,sizeOfOff;
  1396.     int                theDepth;
  1397.  
  1398.     
  1399.     sizeinit();
  1400.     myWindow=NewCWindow(NIL,&allrect,"\pLegend",VISIBLE,noGrowDocProc,
  1401.         (WindowPtr)MOVE_TO_FRONT,TRUE,NIL_REF_CON);
  1402.     mypalettehandle=GetNewPalette(BASE_RES_ID);
  1403.     SetPalette(myWindow,mypalettehandle,FALSE);
  1404.     DisposePalette(mypalettehandle);
  1405.     
  1406.     if(!SectRect(&(*myWindow).portRect,&playrect,&globRect))
  1407.         ExitToShell();    /* ? */
  1408.     tempP.v=globRect.top;
  1409.     tempP.h=globRect.left;
  1410.     LocalToGlobal(&tempP);
  1411.     globRect.top=tempP.v;
  1412.     globRect.left=tempP.h;
  1413.     tempP.v=globRect.bottom;
  1414.     tempP.h=globRect.right;
  1415.     LocalToGlobal(&tempP);
  1416.     globRect.bottom=tempP.v;
  1417.     globRect.right=tempP.h;
  1418.     theMaxDevice=GetMaxDevice(&globRect);
  1419.     oldDevice=GetGDevice();
  1420.     SetGDevice(theMaxDevice);
  1421.  
  1422.     myCGrafPtr=&myCGrafPort;        /*create off screen bitmap*/
  1423.     OpenCPort(myCGrafPtr);
  1424.     theDepth=(**(*myCGrafPtr).portPixMap).pixelSize;
  1425.     offRowBytes=(((theDepth * (width))+15)>>5)<<2;
  1426.     sizeOfOff=(long)(height) *offRowBytes;
  1427.     
  1428.     mypiximage0=NewPtr(sizeOfOff);        /*main offscreen bitimage*/
  1429.     (**(*myCGrafPtr).portPixMap).rowBytes=offRowBytes+0x8000;
  1430.     (**(*myCGrafPtr).portPixMap).bounds=playrect;    
  1431.     (**(*myCGrafPtr).portPixMap).baseAddr=mypiximage0;
  1432.     dumbhandle=(Handle)(**(**theMaxDevice).gdPMap).pmTable;
  1433.     err=HandToHand(&dumbhandle);
  1434.     ourCMHandle=(CTabHandle)dumbhandle;
  1435.     for(i=0;i<=(**ourCMHandle).ctSize;++i)
  1436.         (**ourCMHandle).ctTable[i].value=i;
  1437.     (**ourCMHandle).ctFlags&=0x7ffff;
  1438.     /*(**ourCMHandle).ctSeed=GetCTSeed();*/
  1439.     /* this code is necessary for converting GDevice cluts to Pixmap cluts */    
  1440.     (**(*myCGrafPtr).portPixMap).pmTable=ourCMHandle;
  1441.     
  1442.     mypiximage1=NewPtr(sizeOfOff);        /*background bitimage*/
  1443.     if (!mypiximage1) DoAlert("\pI think we have a memory problem in mypiximage1");
  1444.     pix1=NewPixMap();                /*create pix1 pixmap*/
  1445.     CopyPixMap(myCGrafPtr->portPixMap,pix1);
  1446.     (**pix1).baseAddr=mypiximage1;
  1447.  
  1448.     offRowBytes=(((theDepth * (256))+15)>>4)<<1;
  1449.     sizeOfOff=(long)(256) *offRowBytes;
  1450.     mypiximage2=NewPtr(sizeOfOff);        /*2nd bitimage*/
  1451.     if (!mypiximage2) DoAlert("\pI think we have a memory problem in mypiximage2");
  1452.     pix2=NewPixMap();                /*create pix2 pixmap*/
  1453.     CopyPixMap(myCGrafPtr->portPixMap,pix2);
  1454.     (**pix2).baseAddr=mypiximage2;
  1455.     (**pix2).rowBytes=offRowBytes+0x8000;
  1456.     (**pix2).bounds=sqRect;
  1457.  
  1458.     
  1459.     mypiximage3=NewPtr(sizeOfOff);        /*3rd bitimage*/
  1460.     if (!mypiximage3) DoAlert("\pI think we have a memory problem in mypiximage3");
  1461.     pix3=NewPixMap();                /*create pix3 pixmap*/
  1462.     CopyPixMap(pix2,pix3);
  1463.     (**pix3).baseAddr=mypiximage3;
  1464.  
  1465.     mypiximage4=NewPtr(sizeOfOff);        /*4th bitimage*/
  1466.     if (!mypiximage4) DoAlert("\pI think we have a memory problem in mypiximage3");
  1467.     pix4=NewPixMap();                /*create pix4 pixmap*/
  1468.     CopyPixMap(pix2,pix4);
  1469.     (**pix4).baseAddr=mypiximage4;
  1470.  
  1471.     bitmask3.baseAddr=NewPtr(8192);        /*3rd bitimage mask*/
  1472.     bitmask3.rowBytes=32;
  1473.     SetRect(&r,0,0,256,256);
  1474.     bitmask3.bounds=r;
  1475.  
  1476.  
  1477.     bitmask4.baseAddr=NewPtr(8192);        /*4th bitimage mask*/
  1478.     bitmask4.rowBytes=32;
  1479.     SetRect(&r,0,0,256,256);
  1480.     bitmask4.bounds=r;
  1481.  
  1482.  
  1483.     SetPort((GrafPtr)myCGrafPtr);    /*draw pictures*/
  1484.     if(theDepth<=2) gbasepic=600;
  1485.     LDR(gbasepic+1,0,0);
  1486.     CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(**pix2),&sqRect,&sqRect,srcCopy,0l);
  1487.     LDR(502,0,0);
  1488.     CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(**pix3),&sqRect,&sqRect,srcCopy,0l);    
  1489.     LDR(503,0,0);
  1490.     CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(bitmask3),&sqRect,&sqRect,srcCopy,0l);
  1491.     LDR(504,0,0);
  1492.     CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(**pix4),&sqRect,&sqRect,srcCopy,0l);    
  1493.     LDR(505,0,0);
  1494.     CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(bitmask4),&sqRect,&sqRect,srcCopy,0l);
  1495.     drawsidepanel();
  1496.  
  1497.  
  1498.     SetPort((WindowPtr)myWindow);
  1499.     SetGDevice(oldDevice);
  1500.     (**(*myCGrafPtr).portPixMap).baseAddr=mypiximage0;
  1501.     
  1502. }
  1503. /**openbitmaps**/
  1504. openbitmaps()
  1505. {
  1506.     long            offRowBytes,sizeOfOff;
  1507.  
  1508.     sizeinit();
  1509.     myWindow=NewWindow(NIL,&allrect,"\pLegend",VISIBLE,noGrowDocProc,
  1510.         (WindowPtr)MOVE_TO_FRONT,TRUE,NIL_REF_CON);
  1511.  
  1512.     myGrafPtr=&myGrafPort;            /*create off screen bitmap*/
  1513.     OpenPort(myGrafPtr);
  1514.     offRowBytes=((width+15)>>5)<<2;
  1515.     sizeOfOff=(long)(height)*offRowBytes;
  1516.     
  1517.     mybitimage0=NewPtr(sizeOfOff);        /*main offscreen bitimage*/
  1518.     bit0.baseAddr=mybitimage0;
  1519.     bit0.rowBytes=offRowBytes;
  1520.     bit0.bounds=playrect;
  1521.     SetPortBits(&bit0);
  1522.     
  1523.     mybitimage1=NewPtr(sizeOfOff);        /*background bitimage*/
  1524.     if (!mybitimage1) DoAlert("\pI think we have a memory problem in mybitimage1");
  1525.     bit1.baseAddr=mybitimage1;
  1526.     bit1.rowBytes=offRowBytes;
  1527.     bit1.bounds=playrect;
  1528.  
  1529.     mybitimage2=NewPtr(8192);        /*2nd bitimage*/
  1530.     if (!mybitimage2) DoAlert("\pI think we have a memory problem in mybitimage2");
  1531.     bit2.baseAddr=mybitimage2;
  1532.     bit2.rowBytes=32;
  1533.     bit2.bounds=sqRect;
  1534.  
  1535.     
  1536.     mybitimage3=NewPtr(8192);        /*3rd bitimage*/
  1537.     if (!mybitimage3) DoAlert("\pI think we have a memory problem in mybitimage3");
  1538.     bit3.baseAddr=mybitimage3;
  1539.     bit3.rowBytes=32;
  1540.     bit3.bounds=sqRect;
  1541.  
  1542.     mybitimage4=NewPtr(8192);        /*4th bitimage*/
  1543.     if (!mybitimage4) DoAlert("\pI think we have a memory problem in mybitimage3");
  1544.     bit4.baseAddr=mybitimage4;
  1545.     bit4.rowBytes=32;
  1546.     bit4.bounds=sqRect;
  1547.  
  1548.     bitmask3.baseAddr=NewPtr(8192);        /*3rd bitimage mask*/
  1549.     bitmask3.rowBytes=32;
  1550.     bitmask3.bounds=sqRect;
  1551.  
  1552.  
  1553.     bitmask4.baseAddr=NewPtr(8192);        /*4th bitimage mask*/
  1554.     bitmask4.rowBytes=32;
  1555.     bitmask4.bounds=sqRect;
  1556.  
  1557.  
  1558.     SetPort(myGrafPtr);            /*draw pictures*/
  1559.     LDR(601,0,0);
  1560.     CopyBits(&myGrafPtr->portBits,&bit2,&sqRect,&sqRect,srcCopy,0l);
  1561.     LDR(502,0,0);
  1562.     CopyBits(&myGrafPtr->portBits,&bit3,&sqRect,&sqRect,srcCopy,0l);    
  1563.     LDR(503,0,0);
  1564.     CopyBits(&myGrafPtr->portBits,&(bitmask3),&sqRect,&sqRect,srcCopy,0l);
  1565.     LDR(504,0,0);
  1566.     CopyBits(&myGrafPtr->portBits,&(bit4),&sqRect,&sqRect,srcCopy,0l);    
  1567.     LDR(505,0,0);
  1568.     CopyBits(&myGrafPtr->portBits,&(bitmask4),&sqRect,&sqRect,srcCopy,0l);
  1569.     drawsidepanel();
  1570.  
  1571.  
  1572.     SetPort((WindowPtr)myWindow);
  1573. }
  1574. /**drawsidepanel**/
  1575. drawsidepanel()
  1576. {
  1577.     int    loop;
  1578.     Rect    srcrect,destrect;
  1579.  
  1580.     SetPort(myWindow);
  1581.     LoadPicture(gbasepic);
  1582.     DrawMyPictureat(gThePicture,width,0);
  1583.     if (height>320)            /*extend side panel if required*/
  1584.     {
  1585.         for (loop=320;loop<=height-32;loop+=32)
  1586.         {
  1587.             SetRect(&srcrect,width,224,width+192,256);
  1588.             SetRect(&destrect,width,loop,width+192,loop+32);
  1589.             CopyBits(&(*myWindow).portBits,&(*myWindow).portBits,&srcrect,
  1590.                 &destrect,srcCopy,NIL);
  1591.         }
  1592.     }
  1593.     ReleaseResource((Handle)gThePicture);
  1594.     displayscore();
  1595.     drawhealth();
  1596.     displayitems();
  1597. }
  1598.  
  1599. /***sizeinit***/
  1600. /*this routine finds the screen size and sets the game size*/
  1601. sizeinit()
  1602. {
  1603.     int    top;
  1604.     
  1605.     if (qd.screenBits.bounds.bottom<=342)
  1606.     {
  1607.         top=qd.screenBits.bounds.top+GetMBarHeight();
  1608.     }
  1609.     else top=qd.screenBits.bounds.top+48;
  1610.     lwidth=(qd.screenBits.bounds.right-qd.screenBits.bounds.left-192)/32;
  1611.     lheight=(qd.screenBits.bounds.bottom-top)/32;
  1612.     if (lwidth>MAXLWIDTH) lwidth=MAXLWIDTH;
  1613.     if (lheight>MAXLHEIGHT) lheight=MAXLHEIGHT;
  1614.     natlwidth=lwidth;
  1615.     natlheight=lheight;
  1616.     playregion=NewRgn();
  1617.     sizeset();
  1618.     OffsetRect(&allrect,0,top);
  1619. }
  1620. /**sizeset**/
  1621. sizeset()
  1622. {
  1623.     width=lwidth*32;
  1624.     height=lheight*32;
  1625.     SetRect(&playrect,0,0,width,height);
  1626.     SetRect(&allrect,0,0,width+192,height);
  1627.     RectRgn(playregion,&playrect);
  1628. }
  1629.  
  1630. /*** SetUpDragRect ***/
  1631. SetUpDragRect()
  1632. {
  1633.     gDragRect=qd.screenBits.bounds;
  1634.     gDragRect.left+=DRAG_THRESHOLD;
  1635.     gDragRect.right-=DRAG_THRESHOLD;
  1636.     gDragRect.bottom-=DRAG_THRESHOLD;
  1637. }
  1638.  
  1639. /*** MenuBarInit ***/
  1640.  
  1641. MenuBarInit()
  1642. {
  1643.     Handle    myMenuBar;
  1644.     
  1645.     myMenuBar=GetNewMBar(BASE_RES_ID);
  1646.     SetMenuBar(myMenuBar);
  1647.     
  1648.     gAppleMenu=GetMHandle(APPLE_MENU_ID);
  1649.     gFileMenu=GetMenu(FILE_MENU_ID);
  1650.     gOptionsMenu=GetMenu(OPTIONS_MENU_ID);
  1651.     gMiscMenu=GetMenu(MISC_MENU_ID);
  1652.     gSizeMenu=GetMenu(SIZE_MENU_ID);
  1653.     gStartMenu=GetMenu(START_MENU_ID);
  1654.     gControlMenu=GetMenu(CONTROL_MENU_ID);
  1655.     
  1656.     InsertMenu(gSizeMenu,NOT_A_NORMAL_MENU);
  1657.     InsertMenu(gStartMenu,NOT_A_NORMAL_MENU);
  1658.     InsertMenu(gControlMenu,NOT_A_NORMAL_MENU);
  1659.     
  1660.     AddResMenu(gAppleMenu,'DRVR');
  1661.     DrawMenuBar();
  1662. }
  1663.  
  1664. /*** MiscInit ***/
  1665. MiscInit()
  1666. {
  1667.     SetEventMask(everyEvent);    /*allows key up events to be seen*/
  1668.     mousergn=NewRgn();
  1669.     setmousergn();
  1670.     
  1671.     if(IsIdle()) DisableIdle();    /*For PowerBook only!*/
  1672.  
  1673.     gsimplesound=TRUE;    
  1674.     gsndchannela=NIL;
  1675.     gsndchannelb=NIL;
  1676.     gsndchannelc=NIL;
  1677.     if(SndNewChannel(&gsndchannela,0,0,NIL_POINTER)!=noErr)
  1678.         DoAlert("\pError allocating snd channela");
  1679.     if(!gsimplesound)
  1680.     {
  1681.         if(SndNewChannel(&gsndchannelb,0,0,NIL_POINTER)!=noErr)
  1682.             DoAlert("\pError allocating snd channelb");
  1683.         if(SndNewChannel(&gsndchannelc,0,0,NIL_POINTER)!=noErr)
  1684.             DoAlert("\pError allocating snd channelc");
  1685.     }
  1686.  
  1687.     tocattahandle=GetResource('snd ',TOCATTA_SND);
  1688.     yumhandle=GetResource('snd ',YUM_SND);
  1689.     foothandle=GetResource('snd ',FOOT_SND);
  1690.     arrowhandle=GetResource('snd ',ARROW_SND);
  1691.     ouchhandle=GetResource('snd ',OUCH_SND);
  1692.     keyhandle=GetResource('snd ',KEY_SND);
  1693.     moneyhandle=GetResource('snd ',MONEY_SND);
  1694.     bathandle=GetResource('snd ',BAT_SND);
  1695.     unlockhandle=GetResource('snd ',UNLOCK_SND);
  1696.     poofhandle=GetResource('snd ',POOF_SND);
  1697.     eephandle=GetResource('snd ',EEP_SND);
  1698.     
  1699.     HLock(tocattahandle);
  1700.     HLock(yumhandle);
  1701.     HLock(foothandle);
  1702.     HLock(arrowhandle);
  1703.     HLock(ouchhandle);
  1704.     HLock(keyhandle);
  1705.     HLock(moneyhandle);
  1706.     HLock(bathandle);
  1707.     HLock(unlockhandle);
  1708.     HLock(poofhandle);
  1709.     soundison=TRUE;
  1710.     
  1711.     gtargetcursor=GetCursor(400);
  1712.     /*SetCursor(*gtargetcursor);*/
  1713.     
  1714.     ForeColor(blackColor);
  1715.     BackColor(whiteColor);
  1716.     
  1717.     buttoninit();
  1718.  
  1719.     score=0;
  1720.     numfinal=0;
  1721.     health=healtht=88;
  1722.     startlevel=1;
  1723.     hlevel=2;
  1724.     drawhealth();
  1725. }
  1726. /**setmousergn**/
  1727. /*sets the inactive mouse rgn for waitnextevent*/
  1728. setmousergn()
  1729. {
  1730.     DiffRgn(GetGrayRgn(),((WindowPeek)myWindow)->strucRgn,mousergn);
  1731.     trueplayrect.top=playrect.top;
  1732.     trueplayrect.left=playrect.left;
  1733.     trueplayrect.bottom=playrect.bottom;
  1734.     trueplayrect.right=playrect.right;
  1735.     LocalToGlobal(&topLeft(trueplayrect));
  1736.     LocalToGlobal(&botRight(trueplayrect));
  1737. }
  1738. /*** ButtonInit ***/
  1739. buttoninit()
  1740. {
  1741.     int    loop;
  1742.     Byte    picu[NUM_OF_BUTTONS]={10,12,14,16};
  1743.     Byte    picd[NUM_OF_BUTTONS]={11,13,15,17};
  1744.     
  1745.     for (loop=0;loop<NUM_OF_BUTTONS;loop++)
  1746.     {
  1747.         gbuttonpicu[loop]=GetPicture(picu[loop]+gbasepic);
  1748.         gbuttonpicd[loop]=GetPicture(picd[loop]+gbasepic);
  1749.         gbuttonrect[loop].left=width+32+loop*32;
  1750.         gbuttonrect[loop].top=256;
  1751.         gbuttonrect[loop].right=width+64+loop*32;
  1752.         gbuttonrect[loop].bottom=256+32;
  1753.     }
  1754. }
  1755.  
  1756.  
  1757. /***cleanup***/
  1758. /*last stuff before exiting*/
  1759. cleanup()
  1760. {
  1761.     /*if(SndDisposeChannel(gsndchannela,TRUE)!=noErr)
  1762.         DoAlert("\pInvalid channel queue length");
  1763.     if(!gsimplesound)
  1764.     {
  1765.         if(SndDisposeChannel(gsndchannelb,TRUE)!=noErr)
  1766.             DoAlert("\pInvalid channel queue length");
  1767.         if(SndDisposeChannel(gsndchannelc,TRUE)!=noErr)
  1768.             DoAlert("\pInvalid channel queue length");
  1769.     }
  1770.     */
  1771.     if(IsIdle()) EnableIdle();    /*For PowerBook only!*/
  1772. }
  1773.  
  1774.  
  1775. /**** Misc Subroutines ****/
  1776. /*** IsColor ***/
  1777. Boolean IsColor()
  1778. {
  1779.     SysEnvRec    mySE;
  1780.     SysEnvirons(2,&mySE);
  1781.     return(mySE.hasColorQD);
  1782.     /*return(FALSE);*/
  1783. }
  1784. /*** IsIdle ***/
  1785. /* checks to see if idle is available in portable computers*/
  1786. Boolean IsIdle()
  1787. {
  1788.     OSErr    gestalterr;
  1789.     long    response;
  1790.     gestalterr=Gestalt('powr',&response);
  1791.     if (!gestalterr && (response&1)) return(TRUE);
  1792.     else return(FALSE);
  1793. }
  1794.  
  1795. /*** LoadPicture ***/
  1796. LoadPicture(picnum)
  1797. int    picnum;
  1798. {
  1799.     gThePicture=GetPicture(picnum);
  1800. }
  1801.  
  1802. DrawMyPicture(thePicture)
  1803. PicHandle    thePicture;
  1804. {
  1805.     Rect    myRect,pictureRect;
  1806.     pictureRect=(**(thePicture)).picFrame;
  1807.     myRect.top=0;
  1808.     myRect.bottom=(pictureRect.bottom-pictureRect.top);
  1809.     myRect.left=0;
  1810.     myRect.right=(pictureRect.right-pictureRect.left);
  1811.     DrawPicture(thePicture,&myRect);
  1812. }
  1813.  
  1814. /*** LDR ***/
  1815. /*load, draw, and release picture
  1816. requires a resource #of a pict*/
  1817. LDR(picnum,x,y)
  1818. int    picnum,x,y;
  1819. {
  1820.     PicHandle    ThePicture;
  1821.     
  1822.     ThePicture=GetPicture(picnum);
  1823.     DrawMyPictureat(ThePicture,x,y);
  1824.     ReleaseResource((Handle)ThePicture);
  1825. }
  1826. /***DrawMyPictureat***/
  1827. /*similar to LDR but requires a pichandle*/
  1828. DrawMyPictureat(thePicture,x,y)
  1829. PicHandle    thePicture;
  1830. int    x,y;
  1831. {
  1832.     Rect    myRect,pictureRect;
  1833.     
  1834.     pictureRect=(**(thePicture)).picFrame;
  1835.     myRect.top=y;
  1836.     myRect.bottom=(y+pictureRect.bottom-pictureRect.top);
  1837.     myRect.left=x;
  1838.     myRect.right=(x+pictureRect.right-pictureRect.left);
  1839.     DrawPicture(thePicture,&myRect);
  1840. }
  1841.  
  1842.  
  1843.  
  1844. /***Sounder***/
  1845. sounder(mysndchan,mysoundhandle)
  1846. SndChannelPtr    mysndchan;
  1847. Handle            mysoundhandle;
  1848.  
  1849. {
  1850.     SndCommand        mycommand;
  1851.  
  1852.     if (soundison&&masterstatus!=STATUS_OVER)
  1853.     {
  1854.         if(gsimplesound)
  1855.             mysndchan=gsndchannela;
  1856.         mycommand.cmd=flushCmd;
  1857.         mycommand.param1=0;
  1858.         mycommand.param2=0;
  1859.         if(SndDoImmediate(mysndchan,&mycommand))
  1860.             DoAlert("\pError in snd channel cmd");
  1861.         mycommand.cmd=quietCmd;
  1862.         if(SndDoImmediate(mysndchan,&mycommand))
  1863.             DoAlert("\pError in snd channel cmd");
  1864.             
  1865.         if(SndPlay(mysndchan,mysoundhandle,TRUE))
  1866.             DoAlert("\pError in SndPlay");
  1867.     }
  1868. }
  1869.  
  1870. /***Randomize***/
  1871. /* takes a number and will return a value between zero and range-1 */
  1872. Randomize(range)
  1873. int        range;
  1874. {
  1875.     long    rawresult;
  1876.     rawresult=Random();
  1877.     if(rawresult<0) rawresult *=-1;
  1878.         return((rawresult*range)/32768);
  1879. }
  1880.  
  1881. /***Landscape***/
  1882. /* takes a level and creates the appropriate landscape in the main offscreen
  1883. bitmap AND the background bitmap*/
  1884. landscape(level)
  1885. int        level;
  1886. {
  1887.     Rect    fromrect,torect;
  1888.     int    row,column;
  1889.     
  1890.     for(column=0;column<lwidth;column++)
  1891.         for(row=0;row<lheight;row++)
  1892.             {
  1893.             fromrect=multrect(thislevel[row+lmapy][column+lmapx]%8,
  1894.                 thislevel[row+lmapy][column+lmapx]/8);
  1895.             torect=(multrect(column,row));
  1896.             if (colororbw)
  1897.                 CopyBits((BitMapPtr)&(**pix2),(BitMapPtr)&myCGrafPtr->portPixMap,
  1898.                     &fromrect,&torect,srcCopy,0L);
  1899.             else
  1900.                 CopyBits(&bit2,&myGrafPtr->portBits,
  1901.                     &fromrect,&torect,srcCopy,0L);
  1902.             }
  1903.         if(colororbw)
  1904.             CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,(BitMapPtr)&(**pix1),
  1905.                 &playrect,&playrect,srcCopy,0L);
  1906.         else
  1907.             CopyBits(&myGrafPtr->portBits,&bit1,
  1908.                 &playrect,&playrect,srcCopy,0L);
  1909. }
  1910. /**displayscore**/
  1911. /*also checks if the player gets bonus icecream cone*/
  1912. displayscore()
  1913. {
  1914.     int    loop,number;
  1915.     Rect    fromrect,torect;
  1916.     
  1917.     convertscore();
  1918.     for (loop=3;loop>=0;loop--)
  1919.     {
  1920.         number=digit[loop];
  1921.         SetRect(&fromrect,96+number*16,224,112+number*16,256);
  1922.         SetRect(&torect,width+96-loop*16,64,width+112-loop*16,96);
  1923.         if (colororbw)
  1924.             CopyBits((BitMapPtr)&(**pix2),&(*myWindow).portBits,
  1925.                 &fromrect,&torect,srcCopy,0L);
  1926.         else
  1927.             CopyBits(&bit2,&(*myWindow).portBits,
  1928.                 &fromrect,&torect,srcCopy,0L);
  1929.     }
  1930.     if(gbonuselg && digit[1]<=1 && (digit[2]&1)==0)
  1931.     {    /*player has earned icecream*/
  1932.         gbonuselg=FALSE;
  1933.         addmoremon=FALSE;
  1934.         nummonsters++;
  1935.         monster[nummonsters].status=ICECREAM;
  1936.         monster[nummonsters].dir=0;
  1937.         monster[nummonsters].x=0;
  1938.         if (plx>MAXLWIDTH*16)
  1939.         {
  1940.             monster[nummonsters].dir=1;
  1941.             monster[nummonsters].x=MAXLWIDTH*32;
  1942.         }
  1943.         monster[nummonsters].y=ply;
  1944.         monster[nummonsters].transit=0;
  1945.     }
  1946.     else if (digit[1]>=8) gbonuselg=TRUE;    /*reset*/
  1947. }
  1948. /**convertscore**/
  1949. convertscore()
  1950. {
  1951.     register int    temp;
  1952.     
  1953.     temp=score;
  1954.     digit[3]=temp/1000;
  1955.     temp-=digit[3]*1000;
  1956.     digit[2]=temp/100;
  1957.     temp-=digit[2]*100;
  1958.     digit[1]=temp/10;
  1959.     temp-=digit[1]*10;
  1960.     digit[0]=temp;
  1961. }
  1962. /**displayhealth**/
  1963. displayhealth()
  1964. {
  1965.     Rect    fromrect,torect;
  1966.     int    whichbar;
  1967.  
  1968.     if (health<healtht) 
  1969.     {
  1970.         health++;
  1971.         if (health<healtht-16) health++;
  1972.     }
  1973.     if (health>healtht) health--;
  1974.     
  1975.     if (health>32)
  1976.     {
  1977.         fromrect=minimultrect(1,14);
  1978.         torect.left=width+health+16;
  1979.         torect.top=128;
  1980.         torect.right=width+health+32;
  1981.         torect.bottom=144;
  1982.     }
  1983.     else
  1984.     {
  1985.         if(health<2)
  1986.         {
  1987.             health=2;
  1988.             masterstatus=STATUS_OVER;
  1989.         }
  1990.         if(gred&&(health<30)) whichbar=240;
  1991.         else whichbar=224;
  1992.         SetRect(&fromrect,33-health,whichbar,32,whichbar+16);
  1993.         SetRect(&torect,width+33,128,width+32+health,144);
  1994.     }
  1995.     if (colororbw)
  1996.         CopyBits((BitMapPtr)&(**pix2),&(*myWindow).portBits,
  1997.             &fromrect,&torect,srcCopy,0L);
  1998.     else
  1999.         CopyBits(&bit2,&(*myWindow).portBits,
  2000.             &fromrect,&torect,srcCopy,0L);
  2001. }
  2002. /**drawhealth**/
  2003. /*draws health bar from cleared state*/
  2004. drawhealth()
  2005. {
  2006.     Rect    fromrect,torect;
  2007.     register int    loop;
  2008.  
  2009.     if(health>32)
  2010.     {
  2011.         fromrect=minimultrect(0,14);
  2012.         torect=coorrect(width+32,128,16);
  2013.         if (colororbw)
  2014.             CopyBits((BitMapPtr)&(**pix2),&(*myWindow).portBits,
  2015.                 &fromrect,&torect,srcCopy,0L);
  2016.         else
  2017.             CopyBits(&bit2,&(*myWindow).portBits,
  2018.                 &fromrect,&torect,srcCopy,0L);
  2019.         fromrect=minimultrect(1,14);
  2020.         
  2021.         for(loop=32;loop<=health;loop+=8)
  2022.         {
  2023.             torect=coorrect(width+16+loop,128,16);
  2024.             if (colororbw)
  2025.                 CopyBits((BitMapPtr)&(**pix2),&(*myWindow).portBits,
  2026.                     &fromrect,&torect,srcCopy,0L);
  2027.             else
  2028.                 CopyBits(&bit2,&(*myWindow).portBits,
  2029.                     &fromrect,&torect,srcCopy,0L);
  2030.         }
  2031.     }
  2032.     displayhealth();
  2033. }
  2034. /***displayitems***/
  2035. /*draws items in gitemlist[n]*/
  2036. displayitems()
  2037. {
  2038.     int    loop,mypict;
  2039.     Rect    fromrect,torect;
  2040.  
  2041.     gitemlist[gnumitems]=0;    /*clear this space so it draws clear*/
  2042.     for(loop=0;loop<=gnumitems;loop++)
  2043.     {
  2044.         mypict=gitempic[gitemlist[loop]];
  2045.         fromrect=minimultrect((mypict&15),mypict>>4);
  2046.         torect=coorrect(width+48+loop*16,176,16);
  2047.         if (colororbw)
  2048.             CopyBits((BitMapPtr)&(**pix2),&(*myWindow).portBits,
  2049.                 &fromrect,&torect,srcCopy,0L);
  2050.         else
  2051.             CopyBits(&bit2,&(*myWindow).portBits,
  2052.                 &fromrect,&torect,srcCopy,0L);
  2053.     }
  2054. }
  2055. /**searchitems**/
  2056. /*takes item code and returns with item number with matching code
  2057. if nothing matches this returns -1*/
  2058. int    searchitems(int findme)
  2059. {
  2060.     int    loop,result;
  2061.  
  2062.     result=-1;
  2063.     for(loop=0;loop<gnumitems;loop++)
  2064.         if(gitemlist[loop]==findme) result=loop;
  2065.     return(result);
  2066. }
  2067. /*removeitem*/
  2068. /*takes an item number of removes it from the list*/
  2069. removeitem(removeme)
  2070. int    removeme;
  2071. {
  2072.     int    loop;
  2073.  
  2074.     gnumitems--;
  2075.     if (removeme<gnumitems)
  2076.         for(loop=removeme;loop<gnumitems;loop++)
  2077.             gitemlist[loop]=gitemlist[loop+1];
  2078.     displayitems();
  2079. }
  2080.  
  2081.  
  2082.  
  2083. /***pldraw***/
  2084. pldraw()
  2085. {    
  2086.     Rect    fromrect,torect;
  2087.     
  2088.     fromrect=multrect(plp%8,plp/8);
  2089.     torect=coorrect(plx-mapx,ply-mapy,32);
  2090.     
  2091.     if(colororbw)    
  2092.         CopyMask ((BitMapPtr)&(**pix3),&(bitmask3),(BitMapPtr)&myCGrafPtr->portPixMap,
  2093.             &fromrect,&fromrect,&torect);
  2094.     else
  2095.         CopyMask (&bit3,&(bitmask3),&myGrafPtr->portBits,
  2096.             &fromrect,&fromrect,&torect);
  2097.     
  2098.     finals[numfinal].x=plx-mapx;
  2099.     finals[numfinal].y=ply-mapy;
  2100.     finals[numfinal].size=32;
  2101.     numfinal++;
  2102. }
  2103. /***objectdraw***/
  2104. objectdraw(pic,x,y)
  2105. int    pic,x,y;
  2106. {
  2107.     Rect    fromrect,torect;
  2108.     
  2109.     fromrect=multrect(pic&7,pic>>3);
  2110.     torect=coorrect(x-mapx,y-mapy,32);
  2111.     if(colororbw)
  2112.     {
  2113.         CopyBits((BitMapPtr)&(**pix2),(BitMapPtr)&myCGrafPtr->portPixMap,
  2114.             &fromrect,&torect,srcCopy,0L);
  2115.         CopyBits((BitMapPtr)&(**pix2),(BitMapPtr)&(**pix1),
  2116.             &fromrect,&torect,srcCopy,0L);
  2117.     }
  2118.     else
  2119.     {
  2120.         CopyBits(&bit2,&myGrafPtr->portBits,
  2121.             &fromrect,&torect,srcCopy,0L);
  2122.         CopyBits(&bit2,&bit1,
  2123.             &fromrect,&torect,srcCopy,0L);
  2124.     }
  2125.     finals[numfinal].x=x-mapx;
  2126.     finals[numfinal].y=y-mapy;
  2127.     finals[numfinal].size=32;
  2128.     numfinal++;
  2129. }
  2130. /***overdraw***/
  2131. /*this routine is intended to draw last objects on top*/
  2132. overdraw(pic,x,y)
  2133. int    pic,x,y;
  2134. {
  2135.     Rect    fromrect,torect;
  2136.     
  2137.     fromrect=multrect(pic&7,pic>>3);
  2138.     torect=coorrect(x-mapx,y-mapy,32);
  2139.     if(colororbw)
  2140.     {
  2141.         CopyBits((BitMapPtr)&(**pix2),(BitMapPtr)&myCGrafPtr->portPixMap,
  2142.             &fromrect,&torect,srcCopy,0L);
  2143.     }
  2144.     else
  2145.     {
  2146.         CopyBits(&bit2,&myGrafPtr->portBits,
  2147.             &fromrect,&torect,srcCopy,0L);
  2148.     }
  2149. }
  2150. /***mondraw***/
  2151. mondraw(pic,x,y)
  2152. int            pic;
  2153. register int    x,y;
  2154. {
  2155.     Rect    fromrect,torect;
  2156.     
  2157.     fromrect=multrect(pic&7,pic>>3);
  2158.     torect.left=finals[numfinal].x=x-mapx;        /*i.e. coorrect*/
  2159.     torect.top=finals[numfinal].y=y-mapy;
  2160.     torect.right=x-mapx+32;
  2161.     torect.bottom=y-mapy+32;
  2162.     if(colororbw)
  2163.         CopyMask ((BitMapPtr)&(**pix4),&(bitmask4),(BitMapPtr)&myCGrafPtr->portPixMap,
  2164.             &fromrect,&fromrect,&torect);
  2165.     else
  2166.         CopyMask (&bit4,&(bitmask4),&myGrafPtr->portBits,
  2167.             &fromrect,&fromrect,&torect);
  2168.  
  2169.     /*finals[numfinal].x=x-mapx;
  2170.     finals[numfinal].y=y-mapy;    moved above*/
  2171.     finals[numfinal].size=32;
  2172.     numfinal++;
  2173. }
  2174. /***minidraw***/
  2175. minidraw(pic,x,y)
  2176. int    pic;
  2177. register int x,y;
  2178. {
  2179.     Rect    fromrect,torect;
  2180.     
  2181.     SetRect(&fromrect,(pic&15)*16,(pic>>4)*16,
  2182.         (pic&15)*16+16,(pic>>4)*16+16);    /*minimult*/
  2183.     torect.left=x-mapx;        /*i.e. coorrect*/
  2184.     torect.top=y-mapy;
  2185.     torect.right=x-mapx+16;
  2186.     torect.bottom=y-mapy+16;
  2187.  
  2188.     if(colororbw)
  2189.         CopyMask ((BitMapPtr)&(**pix4),&(bitmask4),(BitMapPtr)&myCGrafPtr->portPixMap,
  2190.             &fromrect,&fromrect,&torect);
  2191.     else
  2192.         CopyMask (&bit4,&(bitmask4),&myGrafPtr->portBits,
  2193.             &fromrect,&fromrect,&torect);
  2194.  
  2195.     finals[numfinal].x=x-mapx;
  2196.     finals[numfinal].y=y-mapy;
  2197.     finals[numfinal].size=16;
  2198.     numfinal++;
  2199. }
  2200. /***dotdraw***/
  2201. dotdraw(x,y)
  2202. register int x,y;
  2203. {
  2204.     Rect    torect;
  2205.     Pattern    thePat;    /* added for calls GetIndPattern and FillRect */
  2206.     
  2207.     torect.left=x-mapx;        /*i.e. coorrect*/
  2208.     torect.top=y-mapy;
  2209.     torect.right=x-mapx+4;
  2210.     torect.bottom=y-mapy+4;
  2211.     
  2212.     if(colororbw) SetPort((GrafPtr)myCGrafPtr);
  2213.     else SetPort(myGrafPtr);
  2214.  
  2215.     GetIndPattern( &thePat, sysPatListID, 1 );     /* system pattern - black */
  2216.     FillRect (&torect, &thePat);  //bsk
  2217.     SetPort(myWindow);
  2218.     
  2219.     finals[numfinal].x=x-mapx;
  2220.     finals[numfinal].y=y-mapy;
  2221.     finals[numfinal].size=4;
  2222.     numfinal++;
  2223. }
  2224.  
  2225.  
  2226. /***Final Draw***/
  2227. /*this routine steps through all the final transfers.  the coordinates
  2228. are in window coornates (i.e. map x and mapy should alread be accounted
  2229. for)*/
  2230. finaldraw()
  2231. {
  2232.     register int    count;
  2233.     Rect            myrect;
  2234.     
  2235.     SetPort(myWindow);
  2236.     if(colororbw)
  2237.     {
  2238.         for (count=0;count<numfinal;count++)
  2239.             {
  2240.                 /*i.e. coorrectl*/
  2241.                 myrect.left=finals[count].x-2;
  2242.                 myrect.top=finals[count].y-2;
  2243.                 myrect.right=finals[count].x+finals[count].size+4;
  2244.                 myrect.bottom=finals[count].y+finals[count].size+4;
  2245.                 CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,&(*myWindow).portBits,
  2246.                     &myrect,&myrect,0,playregion);
  2247.             }
  2248.         for (count=0;count<numfinal;count++)
  2249.             {
  2250.                 /*i.e. coorrect*/
  2251.                 myrect.left=finals[count].x;
  2252.                 myrect.top=finals[count].y;
  2253.                 myrect.right=finals[count].x+finals[count].size;
  2254.                 myrect.bottom=finals[count].y+finals[count].size;
  2255.                 CopyBits((BitMapPtr)&**(pix1),(BitMapPtr)&myCGrafPtr->portPixMap,
  2256.                     &myrect,&myrect,srcCopy,0L);
  2257.             }
  2258.     }
  2259.     else
  2260.     {
  2261.         for (count=0;count<numfinal;count++)
  2262.             {
  2263.                 /*i.e. coorrectl*/
  2264.                 myrect.left=(finals[count].x-2)&65528;
  2265.                 myrect.top=finals[count].y-2;
  2266.                 myrect.right=(finals[count].x+finals[count].size+11)&65528;
  2267.                 myrect.bottom=finals[count].y+finals[count].size+4;
  2268.                 CopyBits(&myGrafPtr->portBits,&(*myWindow).portBits,
  2269.                     &myrect,&myrect,0,playregion);
  2270.             }
  2271.         for (count=0;count<numfinal;count++)
  2272.             {
  2273.                 /*i.e. coorrect*/
  2274.                 myrect.left=(finals[count].x)&65528;
  2275.                 myrect.top=finals[count].y;
  2276.                 myrect.right=(finals[count].x+finals[count].size+7)&65528;
  2277.                 myrect.bottom=finals[count].y+finals[count].size;
  2278.                 CopyBits(&bit1,&myGrafPtr->portBits,
  2279.                     &myrect,&myrect,srcCopy,0L);
  2280.             }
  2281.     }
  2282.  
  2283.     numfinal=0;
  2284. }
  2285.  
  2286. /***multrect***/
  2287. /* takes landscape coordinates and converts to rect based on 32 */
  2288. Rect    multrect(x,y)
  2289. register int        x,y;
  2290. {
  2291.     Rect    r;
  2292.     
  2293.     SetRect(&r,x*32,y*32,x*32+32,y*32+32);
  2294.     return(r);
  2295. }
  2296. /***minimultrect***/
  2297. /* takes landscape coordinates and converts to rect based on 16 */
  2298. Rect    minimultrect(x,y)
  2299. register int        x,y;
  2300. {
  2301.     Rect    r;
  2302.     
  2303.     SetRect(&r,x*16,y*16,x*16+16,y*16+16);
  2304.     return(r);
  2305. }
  2306.  
  2307. /***coorrect***/
  2308. /* takes a coordinate and returns the rect based on 32*/
  2309. /*i.e. SetRect(&r,x,y,x+size,y+size)*/
  2310. Rect    coorrect(x,y,size)
  2311. register int        x,y,size;
  2312. {
  2313.     Rect    r;
  2314.     
  2315.     r.left=x;
  2316.     r.top=y;
  2317.     r.right=x+size;
  2318.     r.bottom=y+size;
  2319.     return(r);
  2320. }
  2321.  
  2322. /***coorrectl***/
  2323. /* takes a coordinate and returns the larger rect*/
  2324. Rect    coorrectl(x,y,size)
  2325. int        x,y,size;
  2326. {
  2327.     Rect    r;
  2328.     
  2329.     r.left=x-2;
  2330.     r.top=y-2;
  2331.     r.right=x+size+4;
  2332.     r.bottom=y+size+4;
  2333.     return(r);
  2334. }
  2335.  
  2336.  
  2337. /***makebitmap***/
  2338. /*set bit map stuff in fields*/
  2339. BitMap    makebitmap()
  2340. {
  2341.     Rect    r;
  2342.     BitMap    mymap;
  2343.     
  2344.     mymap.baseAddr=NewPtr(8192);
  2345.     mymap.rowBytes=32;
  2346.     SetRect(&r,0,0,256,256);
  2347.     mymap.bounds=r;
  2348.     return(mymap);
  2349. }
  2350.  
  2351. /*** DoAlert ***/
  2352. DoAlert(s)
  2353. Str255    s;
  2354. {
  2355.     ParamText(s,NIL_STRING,NIL_STRING,NIL_STRING);
  2356.     NoteAlert(401,NIL_POINTER);
  2357.     ExitToShell();
  2358. }
  2359.  
  2360. /***setlevel***/
  2361. setlevel(level)
  2362. int    level;
  2363. {
  2364.     int    column,row;
  2365.     
  2366.     lmapx=0;
  2367.     lmapy=0;
  2368.     mapx=lmapx*32;
  2369.     mapy=lmapy*32;
  2370.  
  2371.     for(column=0;column<24;column++)
  2372.         for(row=0;row<16;row++)    /* 18? */
  2373.             thislevel[row][column]=dungeon[level][row][column];
  2374.     for(column=0;column<4;column++)        /*clear(lock) all gates*/
  2375.         gatestatus[column]=0;
  2376.     landscaperequest=faderequest=TRUE;
  2377.     datainit();
  2378.     playerinit();
  2379.     ObscureCursor();
  2380. }
  2381. /**offtoon**/
  2382. /*copies the bit image info from offscreen to on*/
  2383. offtoon()
  2384. {
  2385.     if(colororbw)
  2386.         CopyBits((BitMapPtr)&myCGrafPtr->portPixMap,&(*myWindow).portBits,
  2387.             &playrect,&playrect,0,NIL_POINTER);
  2388.     else
  2389.         CopyBits(&myGrafPtr->portBits,&(*myWindow).portBits,
  2390.             &playrect,&playrect,0,NIL_POINTER);
  2391.  
  2392. }
  2393. /**ontooff**/
  2394. /*copies the bit image info from offscreen to on*/
  2395. ontooff()
  2396. {
  2397.     if(colororbw)
  2398.         CopyBits(&(*myWindow).portBits,(BitMapPtr)&myCGrafPtr->portPixMap,
  2399.             &playrect,&playrect,0,NIL_POINTER);
  2400.     else
  2401.         CopyBits(&(*myWindow).portBits,&myGrafPtr->portBits,
  2402.             &playrect,&playrect,0,NIL_POINTER);
  2403.  
  2404. }
  2405. /**playerinit**/
  2406. playerinit()
  2407. {
  2408.     pls=plt=pld=0;
  2409.     plx=32*startx[level];
  2410.     ply=32*starty[level];
  2411.     plp=8;
  2412. }
  2413. /**datainit**/
  2414. /* converts all the data stored in data arrays into proper structures*/
  2415. datainit()
  2416. {
  2417.     int    loop;
  2418.         
  2419.     for (loop=0;loop<MAXMONSTERS;loop++)
  2420.         monster[loop].status=0;
  2421.     for (loop=0;loop<MAXMISSILES;loop++)
  2422.         missile[loop].status=3;
  2423.     missile[0].status=0;
  2424.  
  2425.     numobjects=nummonsters=0;    
  2426.     for (loop=0;loop<MAXOBJECTS;loop++)
  2427.     {
  2428.         if (data[level][loop][4]==1)
  2429.         {
  2430.             /*it's an object!*/
  2431.             object[numobjects].status=data[level][loop][0];
  2432.             object[numobjects].dir=data[level][loop][1];
  2433.             object[numobjects].x=data[level][loop][2]*32;
  2434.             object[numobjects].y=data[level][loop][3]*32;
  2435.             object[numobjects].transit=0;
  2436.             object[numobjects].pic=data[level][loop][5];
  2437.             object[numobjects].alt1=data[level][loop][6];
  2438.             object[numobjects].alt2=data[level][loop][7];
  2439.             numobjects++;
  2440.         }
  2441.         else if(data[level][loop][4]==2)
  2442.         {
  2443.             /*it's a monster*/
  2444.             monster[nummonsters].status=data[level][loop][0];
  2445.             monster[nummonsters].dir=data[level][loop][1];
  2446.             monster[nummonsters].x=data[level][loop][2]*32;
  2447.             monster[nummonsters].y=data[level][loop][3]*32;
  2448.             monster[nummonsters].transit=0;
  2449.             monster[nummonsters].pic=data[level][loop][5]*32;
  2450.             monster[nummonsters].alt1=data[level][loop][6]*32;
  2451.             monster[nummonsters].alt2=data[level][loop][7]*32;
  2452.             nummonsters++;
  2453.         }
  2454.     }
  2455. }
  2456.  
  2457.  
  2458.  
  2459. /***testscroll***/
  2460. testscroll()
  2461. {
  2462.     if (plx-mapx>width-64) scrollleft();
  2463.     if (plx-mapx<32) scrollright();
  2464.     if (ply-mapy>height-64) scrollup();
  2465.     if (ply-mapy<32) scrolldown();
  2466. }
  2467. scrollleft()
  2468. {
  2469.     int    oldlmapx;
  2470.     
  2471.     oldlmapx=lmapx;
  2472.     lmapx=lmapx+lwidth-3;
  2473.     if (lmapx>24-lwidth) lmapx=24-lwidth;
  2474.     mapx=lmapx*32;
  2475.     if(lmapx!=oldlmapx) landscaperequest=TRUE;    /*if no change then no landscape*/
  2476. }
  2477. scrollright()
  2478. {
  2479.     int    oldlmapx;
  2480.     
  2481.     oldlmapx=lmapx;
  2482.     lmapx=lmapx-lwidth+3;
  2483.     if(lmapx<0) lmapx=0;
  2484.     mapx=lmapx*32;
  2485.     if(lmapx!=oldlmapx) landscaperequest=TRUE;    /*if no change then no landscape*/
  2486. }
  2487. scrollup()
  2488. {
  2489.     lmapy=lmapy+lheight-3;
  2490.     if (lmapy>16-lheight) lmapy=16-lheight;
  2491.     mapy=lmapy*32;
  2492.     landscaperequest=TRUE;
  2493. }
  2494. scrolldown()
  2495. {
  2496.     lmapy=lmapy-lheight+3;
  2497.     if(lmapy<0)lmapy=0;
  2498.     mapy=lmapy*32;
  2499.     landscaperequest=TRUE;
  2500. }
  2501.  
  2502. /***player***/
  2503. player()
  2504. {
  2505.     int        temp;
  2506.     
  2507.     ploccuset();    /*modify occuvalues here*/
  2508.     switch(pls)
  2509.     {
  2510.         case    0:    /*wait*/
  2511.             temp=keydir();
  2512.             if (temp>-1)
  2513.             {
  2514.                 pls=4;
  2515.                 pld=temp;
  2516.                 plt=0;
  2517.             }
  2518.             break;
  2519.         case    4:    /*walk*/
  2520.             plp=plwalkpic[pld][plt];
  2521.             plt++;
  2522.             if (plt>9) plt=0;
  2523.             if(!gsimplesound)
  2524.             {
  2525.                 if(plt==3) sounder(gsndchannela,foothandle);
  2526.                 if(plt==8) sounder(gsndchannelb,foothandle);
  2527.             }
  2528.             occumaster=2;
  2529.             if(gkeyormouse) cango2(&plx,&ply,dir2x[pld],dir2y[pld],pld,31);
  2530.             else cango(&plx,&ply,dir2x[pld],dir2y[pld],pld,31);
  2531.             temp=keydir();
  2532.             if (temp==pld) break;
  2533.             if (temp<0)
  2534.             {
  2535.                 pls=plt=0;
  2536.                 break;
  2537.             }
  2538.             pld=temp;
  2539.             break;
  2540.         case 5:    /*cloud*/
  2541.             plp=plt/3+32;
  2542.             if (plt++>25) pls=6;
  2543.             break;
  2544.         case 6: /*none*/
  2545.             break;
  2546.     }
  2547.     pldraw();
  2548.     ploccurestore();    /*restore occuvals*/
  2549. }
  2550. /**keydir**/
  2551. /*returns a direction value upon return
  2552. -1 indicates no direction*/
  2553. short    keydir()
  2554. {
  2555.     int    value;
  2556.     Point    mypoint;
  2557.     
  2558.     value=-1;
  2559.     if(gkeyormouse)
  2560.     {
  2561.         mypoint.h=gTheEvent.where.h-16+mapx;
  2562.         mypoint.v=gTheEvent.where.v-16+mapy;
  2563.         GlobalToLocal(&mypoint);
  2564.         if(mypoint.h<plx+8 && mypoint.h>plx-8 &&
  2565.             mypoint.v<ply+8 && mypoint.v>ply-8) return(-1);
  2566.         if(mypoint.h<plx-1 && mypoint.v<ply+16 && mypoint.v>ply-16) return(1);
  2567.         if(mypoint.h>plx+1 && mypoint.v<ply+16 && mypoint.v>ply-16) return(0);
  2568.         if(mypoint.h<plx+16 && mypoint.h>plx-16 && mypoint.v>ply) return(3);
  2569.         if(mypoint.h<plx+16 && mypoint.h>plx-16 && mypoint.v<ply) return(2);
  2570.         if(mypoint.h<plx && mypoint.v>ply) value=6;
  2571.         if(mypoint.h>plx && mypoint.v>ply) value=7;
  2572.         if(mypoint.h>plx && mypoint.v<ply) value=4;
  2573.         if(mypoint.h<plx && mypoint.v<ply) value=5;
  2574.     }
  2575.     else
  2576.     {
  2577.         if (ispressed(88)||ispressed(0X02)||ispressed(0x7c)) value=0;    /*right*/
  2578.         else if(ispressed2(86)||ispressed2(0x00)||ispressed(0x7b)) value=1;    /*left*/
  2579.         else if(ispressed2(91)||ispressed2(0x0d)||ispressed(0x7e)) value=2;    /*up*/
  2580.         else if(ispressed2(84)||ispressed2(0x07)||ispressed(0x7d)) value=3;    /*down*/
  2581.         else if(ispressed2(92) || ispressed2(0x0e)) value=4;    /*ur*/
  2582.         else if(ispressed2(89) || ispressed2(0x0c)) value=5;    /*ul*/
  2583.         else if(ispressed2(83) || ispressed2(0x06)) value=6;    /*dl*/
  2584.         else if(ispressed2(85) || ispressed2(0x08)) value=7;    /*dr*/
  2585.         /*else value=-1;*/
  2586.     }
  2587.     return(value);
  2588. }
  2589.  
  2590. /**occuset**/
  2591. /* in this order: mioccuset,ploccuset,ploccurestore*/
  2592. mioccuset()
  2593. {
  2594.     occuval[42]=0;    /*opad*/
  2595. }
  2596. ploccuset()
  2597. {
  2598.     occuval[24]=0;    /*apple*/
  2599.     occuval[32]=0;    /*superapple*/
  2600.     occuval[29]=0;    /*treasure*/
  2601.     occuval[40]=1;    /*xpad*/
  2602. }
  2603. ploccurestore()    /*this is the default for all objects and monsters*/
  2604. {
  2605.     occuval[24]=1;    /*apple*/
  2606.     occuval[32]=1;    /*superapple*/
  2607.     occuval[29]=1;    /*treasure*/
  2608.     occuval[40]=0;    /*xpad*/
  2609.     occuval[42]=1;    /*opad*/
  2610. }
  2611.  
  2612. /***objects***/
  2613. objects()
  2614. {
  2615.     int    loop;
  2616.     
  2617.     for(loop=0;loop<numobjects;loop++)
  2618.     {
  2619.         doobject(&object[loop]);
  2620.     }
  2621. }
  2622. /**doobject**/
  2623. void    doobject(struct objectdata *myobject)
  2624. {
  2625.     switch((*myobject).status)
  2626.     {
  2627.         case 0:
  2628.             break;
  2629.         case APPLE:
  2630.             if (within(plx,ply,(*myobject).x,(*myobject).y,12,12))
  2631.             {
  2632.                 objectdraw(25,(*myobject).x,(*myobject).y);
  2633.                 thislevel[(*myobject).y/32][(*myobject).x/32]=0;
  2634.                 (*myobject).status=0;
  2635.                 healtht=healtht+32;
  2636.                 if(healtht>MAXHEALTH) healtht=MAXHEALTH;
  2637.                 sounder(gsndchannelc,yumhandle);
  2638.             }
  2639.             break;
  2640.         case SUPERAPPLE:
  2641.             if (within(plx,ply,(*myobject).x,(*myobject).y,12,12))
  2642.             {
  2643.                 objectdraw(33,(*myobject).x,(*myobject).y);
  2644.                 thislevel[(*myobject).y/32][(*myobject).x/32]=0;
  2645.                 (*myobject).status=0;
  2646.                 healtht=MAXHEALTH;
  2647.                 /*if(healtht>MAXHEALTH) healtht=MAXHEALTH;*/
  2648.                 sounder(gsndchannelc,yumhandle);
  2649.             }
  2650.             break;
  2651.         case KEY:        /*key*/
  2652.             if (within(plx,ply,(*myobject).x,(*myobject).y,12,12))
  2653.             {
  2654.                 objectdraw(0,(*myobject).x,(*myobject).y);
  2655.                 thislevel[(*myobject).y/32][(*myobject).x/32]=0;
  2656.                 (*myobject).status=0;
  2657.                 gitemlist[gnumitems]=(*myobject).alt2;
  2658.                 gnumitems++;
  2659.                 displayitems();
  2660.                 sounder(gsndchannelc,keyhandle);
  2661.             }
  2662.             break;
  2663.         case TREASURE:        /*treasure*/
  2664.             if (within(plx,ply,(*myobject).x,(*myobject).y,16,16))
  2665.             {
  2666.                 objectdraw((*myobject).pic,(*myobject).x,(*myobject).y);
  2667.                 thislevel[(*myobject).y/32][(*myobject).x/32]=(*myobject).pic;
  2668.                 (*myobject).status=0;
  2669.                 if((*myobject).alt1) score+=(*myobject).alt1;
  2670.                 else score+=5;
  2671.                 displayscore();
  2672.                 sounder(gsndchannelc,moneyhandle);
  2673.             }
  2674.             break;
  2675.         case KEYHOLE:
  2676.             if (within(plx,ply,(*myobject).x,(*myobject).y,16,16))
  2677.             {
  2678.                 if (searchitems((*myobject).alt2)==-1) break;
  2679.                 objectdraw(0,(*myobject).x,(*myobject).y);
  2680.                 thislevel[(*myobject).y/32][(*myobject).x/32]=0;
  2681.                 (*myobject).status=0;
  2682.                 removeitem(searchitems((*myobject).alt2));
  2683.                 gatestatus[(*myobject).alt1]=1;
  2684.                 sounder(gsndchannelc,unlockhandle);
  2685.             }
  2686.             break;
  2687.         case GATE:
  2688.             gvara=(*myobject).alt1;
  2689.             if (gatestatus[gvara])
  2690.             {
  2691.                 objectdraw(21,(*myobject).x,(*myobject).y);
  2692.                 objectdraw(0,(*myobject).x+32,(*myobject).y);
  2693.                 objectdraw(22,(*myobject).x+64,(*myobject).y);
  2694.                 thislevel[(*myobject).y/32][(*myobject).x/32]=21;
  2695.                 thislevel[(*myobject).y/32][(*myobject).x/32+1]=0;
  2696.                 thislevel[(*myobject).y/32][(*myobject).x/32+2]=22;
  2697.                 (*myobject).status=0;
  2698.             }
  2699.             break;
  2700.         case RING:        /*ring*/
  2701.             if (within(plx,ply,(*myobject).x,(*myobject).y,12,12))
  2702.             {
  2703.                 objectdraw(46,(*myobject).x,(*myobject).y);
  2704.                 thislevel[(*myobject).y/32][(*myobject).x/32]=46;
  2705.                 (*myobject).status=0;
  2706.                 gitemlist[gnumitems]=RINGITEM;
  2707.                 gnumitems++;
  2708.                 displayitems();
  2709.                 sounder(gsndchannelc,keyhandle);
  2710.             }
  2711.             break;
  2712.     }
  2713. }
  2714. /**within**/
  2715. /*returns true if points are within tolerance of each other
  2716. i.e. if any overlapping of "boxes" occurs.  coordinates are
  2717. upper left and boxes are square*/
  2718. Boolean    within(int x, int y, int x2, int y2,int size,int size2)
  2719. {
  2720.     if (x<x2+size2 && x+size>x2 && y<y2+size2 && y+size>y2)
  2721.         return(TRUE);
  2722.     else
  2723.         return(FALSE);
  2724. }
  2725. /***objects2***/
  2726. objects2()
  2727. {
  2728.     int    loop;
  2729.     
  2730.     for(loop=0;loop<numobjects;loop++)
  2731.     {
  2732.         doobject2(&object[loop]);
  2733.     }
  2734. }
  2735. /**doobject2**/
  2736. /* for objects that must appear on top*/
  2737. void    doobject2(struct objectdata *myobject)
  2738. {
  2739.     int    addmybuggles,loop;
  2740.     
  2741.     switch((*myobject).status)
  2742.     {
  2743.         case 0:
  2744.             break;
  2745.         case MACHINE:
  2746.             if(gcounter&1)
  2747.             if(addmoremon&&((Random()&31)==0)) addmybuggles=1;
  2748.             else addmybuggles=0;
  2749.             if(nummonsters<3) addmybuggles=1;
  2750.             if(gcounter&1) (*myobject).transit++;    
  2751.             if((*myobject).transit<(*myobject).alt1) addmybuggles=0;
  2752.             if(nummonsters+4>MAXMONSTERS) addmybuggles=0;
  2753.             for(loop=nummonsters;loop>=0;loop--)
  2754.             {
  2755.                 if (monster[loop].status>=32 &&
  2756.                     monster[loop].x>=(*myobject).x-64 &&
  2757.                     monster[loop].x<=(*myobject).x &&
  2758.                     monster[loop].y>=(*myobject).y-32 &&
  2759.                     monster[loop].y<=(*myobject).y+32)
  2760.                 {
  2761.                     addmybuggles=0;
  2762.                     overdraw(28,(*myobject).x,(*myobject).y);
  2763.                     break;
  2764.                 }
  2765.             }
  2766.             if (addmybuggles)
  2767.             {
  2768.                 addmoremon=FALSE;
  2769.                 (*myobject).transit=0;
  2770.                 nummonsters++;
  2771.                 monster[nummonsters].status=BUGGLES;
  2772.                 monster[nummonsters].dir=1;
  2773.                 monster[nummonsters].x=(*myobject).x;
  2774.                 monster[nummonsters].y=(*myobject).y;
  2775.                 monster[nummonsters].transit=0;
  2776.                 monster[nummonsters].pic=4;
  2777.                 monster[nummonsters].alt1=0;
  2778.                 monster[nummonsters].alt2=24;    /*temp ineffective*/
  2779.             }
  2780.             break;
  2781.         case INLETL:
  2782.             overdraw(30,(*myobject).x,(*myobject).y);
  2783.             break;
  2784.         case INLETR:
  2785.             overdraw(31,(*myobject).x,(*myobject).y);
  2786.             break;
  2787.     }
  2788. }
  2789.  
  2790. /***missiles***/
  2791. missiles()
  2792. {
  2793.     int    loop;
  2794.     
  2795.     mioccuset();
  2796.     occumaster=0;
  2797.     for(loop=0;loop<MAXMISSILES;loop++)
  2798.     {
  2799.         domissile(&missile[loop]);
  2800.     }
  2801. }
  2802. /***domissile***/
  2803. void    domissile(struct missiledata *mymissile)
  2804. {
  2805.     switch((*mymissile).status)
  2806.     {
  2807.         case 0:    /*unused player missile*/
  2808.             if (ispressed(87) || ispressed(0x31) ||
  2809.                 (Button()&&PtInRect(gTheEvent.where,&trueplayrect)))
  2810.             {
  2811.                 if(masterstatus!=STATUS_OVER)(*mymissile).status=1;
  2812.                 (*mymissile).dir=pld;
  2813.                 (*mymissile).transit=0;
  2814.                 (*mymissile).x=(plx+10)&32760; /*mask out 1,2 and 4*/
  2815.                 (*mymissile).y=ply+8;
  2816.                 (*mymissile).x+=dir12x[(*mymissile).dir];
  2817.                 (*mymissile).y+=dir12y[(*mymissile).dir];
  2818.                 (*mymissile).pic=missilepic[(*mymissile).dir];
  2819.                 sounder(gsndchannelc,arrowhandle);
  2820.             }
  2821.             break;
  2822.         case 1:    /*player missile in flight*/
  2823.             finals[numfinal].x=(*mymissile).x-mapx;    /*erase old stuff*/
  2824.             finals[numfinal].y=(*mymissile).y-mapy;
  2825.             finals[numfinal].size=16;
  2826.             numfinal++;
  2827.             if((*mymissile).transit++>30)
  2828.             {
  2829.                 (*mymissile).status=0;
  2830.                 break;
  2831.             }
  2832.             (*mymissile).x+=dir12x[(*mymissile).dir];
  2833.             (*mymissile).y+=dir12y[(*mymissile).dir];
  2834.             if (occupied((*mymissile).x+8,(*mymissile).y+8))
  2835.             {
  2836.                 (*mymissile).status=2;
  2837.                 (*mymissile).transit=0;
  2838.                 (*mymissile).dir=rebound[(*mymissile).dir];
  2839.                 break;
  2840.             }
  2841.             minidraw((*mymissile).pic,(*mymissile).x,(*mymissile).y);
  2842.             break;
  2843.         case 2:    /*missile explode*/
  2844.             (*mymissile).pic=arrowexplodepic[(*mymissile).transit];
  2845.             (*mymissile).x+=dir2x[(*mymissile).dir];
  2846.             (*mymissile).y+=dir2y[(*mymissile).dir];
  2847.             minidraw((*mymissile).pic,(*mymissile).x,(*mymissile).y);
  2848.             if((*mymissile).transit++>3) (*mymissile).status=0;
  2849.             break;
  2850.         case 3: /*unused missile*/
  2851.             break;
  2852.         case 4: /*firebolt*/
  2853.             finals[numfinal].x=(*mymissile).x-mapx;    /*erase old stuff*/
  2854.             finals[numfinal].y=(*mymissile).y-mapy;
  2855.             finals[numfinal].size=4;
  2856.             numfinal++;
  2857.             if((*mymissile).transit++>70)
  2858.             {
  2859.                 (*mymissile).status=3;
  2860.                 break;
  2861.             }
  2862.             if(within(plx,ply,(*mymissile).x,(*mymissile).y,28,4))
  2863.             {
  2864.                 healtht=healtht-10;
  2865.                 (*mymissile).status=3;
  2866.                 sounder(gsndchannelc,ouchhandle);
  2867.                 break;
  2868.             }
  2869.             (*mymissile).x+=dir1x[(*mymissile).dir]*6;
  2870.             (*mymissile).y+=dir1y[(*mymissile).dir]*6;
  2871.             dotdraw((*mymissile).x,(*mymissile).y);
  2872.             break;
  2873.     }
  2874. }
  2875.             
  2876. /***monsters***/
  2877. monsters()
  2878. {
  2879.     for(gloop=nummonsters;gloop>=0;gloop--)
  2880.     {
  2881.         domonster(&monster[gloop]);
  2882.     }
  2883. }
  2884. /**domonster**/
  2885. void    domonster(struct monsterdata *mymonster)
  2886. {
  2887.     int    dir;
  2888.     switch((*mymonster).status)
  2889.     {
  2890.         case 0:        /*null monster*/
  2891.             break;
  2892.         case BUGGLES:
  2893.             (*mymonster).transit++;
  2894.             if((*mymonster).transit>5) (*mymonster).transit=0;
  2895.             dir=getdir((*mymonster).x,(*mymonster).y);
  2896.             if((*mymonster).dir!=dir)
  2897.             {
  2898.                 if((*mymonster).alt1++>23)
  2899.                 {
  2900.                     (*mymonster).alt1=0;
  2901.                     (*mymonster).dir=dir;
  2902.                 }
  2903.             }
  2904.             (*mymonster).pic=bugglewalkpic[(*mymonster).dir][(*mymonster).transit];
  2905.             occumaster=1;
  2906.             cango(&(*mymonster).x,&(*mymonster).y,
  2907.                 dir2x[(*mymonster).dir],dir2y[(*mymonster).dir],(*mymonster).dir,31);
  2908.             mondraw((*mymonster).pic,(*mymonster).x,(*mymonster).y);
  2909.             if(missile[0].status==1)
  2910.             {
  2911.                 if(within(missile[0].x+6,missile[0].y+6,(*mymonster).x,
  2912.                     (*mymonster).y,4,32))
  2913.                 {
  2914.                     missile[0].status=2;
  2915.                     missile[0].transit=0;
  2916.                     (*mymonster).status=4;
  2917.                     (*mymonster).transit=0;
  2918.                     score+=1;
  2919.                     displayscore();
  2920.                     sounder(gsndchannelc,poofhandle);
  2921.                 }
  2922.             }
  2923.             if ((*mymonster).alt2) (*mymonster).alt2--;
  2924.             else if(within(plx,ply,(*mymonster).x,(*mymonster).y,33,33))
  2925.             {
  2926.                 sounder(gsndchannelc,ouchhandle);
  2927.                 healtht=healtht-10;
  2928.                 (*mymonster).alt2=16;
  2929.             }
  2930.             break;
  2931.         case BAT:
  2932.             (*mymonster).transit++;
  2933.             if((*mymonster).transit>15) (*mymonster).transit=0;
  2934.             dir=getdir((*mymonster).x,(*mymonster).y);
  2935.             if((*mymonster).dir!=dir)
  2936.             {
  2937.                 if((*mymonster).pic++>8)
  2938.                 {
  2939.                     (*mymonster).pic=0;    /*not actually used for pic*/
  2940.                     (*mymonster).dir=dir;
  2941.                 }
  2942.             }
  2943.             if(Randomize(50)<1) (*mymonster).dir=Randomize(9);
  2944.             (*mymonster).x+=dir1x[(*mymonster).dir];
  2945.             (*mymonster).y+=dir1y[(*mymonster).dir];
  2946.             minidraw(batpic[(*mymonster).transit],
  2947.                 (*mymonster).x,(*mymonster).y);
  2948.             if(missile[0].status==1)
  2949.             {
  2950.                 if(within(missile[0].x+8,missile[0].y+8,(*mymonster).x+2,
  2951.                     (*mymonster).y,2,14))
  2952.                 {
  2953.                     missile[0].status=2;
  2954.                     missile[0].transit=0;
  2955.                     (*mymonster).status=3;
  2956.                     (*mymonster).transit=0;
  2957.                     /*score+=1;
  2958.                     displayscore();*/
  2959.                     sounder(gsndchannelc,bathandle);
  2960.                 }
  2961.             }
  2962.             if(within(plx,ply,(*mymonster).x,(*mymonster).y,34,14))
  2963.             {
  2964.                 sounder(gsndchannelc,ouchhandle);
  2965.                 healtht=healtht-10;
  2966.                 (*mymonster).status=3;
  2967.                 (*mymonster).transit=7;
  2968.             }
  2969.  
  2970.             break;
  2971.         case 3:        /*deadbat*/
  2972.             (*mymonster).y+=3;
  2973.             minidraw(deadbatpic[(*mymonster).transit],
  2974.                 (*mymonster).x,(*mymonster).y);
  2975.             if(++(*mymonster).transit>=8)
  2976.             {
  2977.                 (*mymonster).status=2;
  2978.                 (*mymonster).x=(*mymonster).alt1;
  2979.                 (*mymonster).y=(*mymonster).alt2;
  2980.                 (*mymonster).transit=0;
  2981.             }
  2982.             break;
  2983.         case DEAD:
  2984.             (*mymonster).pic=scorerollpic[(*mymonster).transit];
  2985.             /*numfinal++;*/
  2986.             mondraw((*mymonster).pic,(*mymonster).x,(*mymonster).y);
  2987.             if(++(*mymonster).transit>23)
  2988.             {
  2989.                 (*mymonster).status=0;
  2990.                 (*mymonster).status=monster[nummonsters].status;
  2991.                 (*mymonster).dir=monster[nummonsters].dir;
  2992.                 (*mymonster).x=monster[nummonsters].x;
  2993.                 (*mymonster).y=monster[nummonsters].y;
  2994.                 (*mymonster).transit=monster[nummonsters].transit;
  2995.                 (*mymonster).pic=monster[nummonsters].pic;
  2996.                 (*mymonster).alt1=monster[nummonsters].alt1;
  2997.                 (*mymonster).alt2=monster[nummonsters].alt2;
  2998.                 nummonsters--;
  2999.             }
  3000.             break;
  3001.         case GHOST:
  3002.             (*mymonster).transit=(++(*mymonster).transit&63);
  3003.             dir=getdir2((*mymonster).x,(*mymonster).y);
  3004.             if(((*mymonster).dir!=dir)||((*mymonster).alt1>60))
  3005.                 if(++(*mymonster).alt1>70)
  3006.                 {
  3007.                     (*mymonster).alt1=(gloop&15);
  3008.                     (*mymonster).dir=dir;
  3009.                 }
  3010.             if((*mymonster).alt1<=60)
  3011.             {
  3012.                 (*mymonster).x+=dir2x[(*mymonster).dir];
  3013.                 (*mymonster).y+=dir2y[(*mymonster).dir];
  3014.             }
  3015.             mondraw(ghostpic[(*mymonster).transit>>3],
  3016.                 (*mymonster).x,(*mymonster).y);
  3017.             if ((*mymonster).alt2) (*mymonster).alt2--;
  3018.             else if(within(plx,ply,(*mymonster).x,(*mymonster).y,28,30))
  3019.             {
  3020.                 sounder(gsndchannelc,ouchhandle);
  3021.                 healtht=healtht-6;
  3022.                 (*mymonster).alt2=16;
  3023.             }
  3024.             break;
  3025.         case POOLBALL:
  3026.             (*mymonster).transit++;
  3027.             if((*mymonster).transit>15) (*mymonster).transit=0;
  3028.             (*mymonster).pic=poolballpic[(*mymonster).dir][(*mymonster).transit];
  3029.             (*mymonster).x+=dir2x[(*mymonster).dir];
  3030.             mondraw((*mymonster).pic,(*mymonster).x,(*mymonster).y);
  3031.             if(missile[0].status==1)
  3032.             {
  3033.                 if(within(missile[0].x+6,missile[0].y+6,(*mymonster).x,
  3034.                     (*mymonster).y,4,32))
  3035.                 {
  3036.                     missile[0].status=2;
  3037.                     missile[0].transit=0;
  3038.                 }
  3039.             }
  3040.             if(within(plx,ply,(*mymonster).x,(*mymonster).y,16,16))
  3041.             {
  3042.                 health=healtht=1;
  3043.                 /*drawsidepanel();*/
  3044.             }
  3045.             
  3046.             if((*mymonster).x<-4) (*mymonster).x=736;            
  3047.             break;
  3048.         case BEHOLD:
  3049.             (*mymonster).dir=getdir((*mymonster).x,(*mymonster).y);
  3050.             (*mymonster).x+=dir1x[(*mymonster).dir];
  3051.             (*mymonster).y+=dir1y[(*mymonster).dir];
  3052.             if((*mymonster).transit) (*mymonster).transit++;
  3053.             (*mymonster).transit=(*mymonster).transit&7;
  3054.             gvara=undu[((*mymonster).alt1++)>>2&3];
  3055.             mondraw(beholdpic[(*mymonster).transit],
  3056.                 (*mymonster).x,(*mymonster).y+gvara);
  3057.             if(!(Random()&63))(*mymonster).transit=1;    /*blink*/
  3058.             
  3059.             if((*mymonster).alt2<=0)
  3060.                 for (gvara=1;gvara<MAXMISSILES;gvara++)
  3061.                 {
  3062.                     if(missile[gvara].status==3)
  3063.                     {
  3064.                         missile[gvara].status=4;
  3065.                         missile[gvara].transit=0;
  3066.                         missile[gvara].x=(*mymonster).x+16;
  3067.                         missile[gvara].y=(*mymonster).y+16;
  3068.                         missile[gvara].dir=(*mymonster).dir;
  3069.                         (*mymonster).alt2=10;
  3070.                         break;
  3071.                     }
  3072.                 }
  3073.             else (*mymonster).alt2--;
  3074.             
  3075.             if(missile[0].status==1)
  3076.             {
  3077.                 if(within(missile[0].x+6,missile[0].y+6,(*mymonster).x,
  3078.                     (*mymonster).y,4,32))
  3079.                 {
  3080.                     missile[0].status=2;
  3081.                     missile[0].transit=0;
  3082.                     missile[0].dir=rebound[missile[0].dir];
  3083.                     
  3084.                     (*mymonster).transit=0;
  3085.                     if((*mymonster).pic++<3)
  3086.                         (*mymonster).status=BEHOLDH;
  3087.                     else
  3088.                     {
  3089.                         (*mymonster).status=DEAD;
  3090.                         score+=1;
  3091.                         displayscore();
  3092.                     }
  3093.                 }
  3094.             }
  3095.             break;
  3096.         case BEHOLDH:
  3097.             if(++(*mymonster).transit>127)
  3098.                 (*mymonster).status=BEHOLD;
  3099.             gvara=undu[((*mymonster).alt1++)&3];
  3100.             if((*mymonster).transit>7) mondraw(53,(*mymonster).x,(*mymonster).y);
  3101.             else mondraw(50,(*mymonster).x,(*mymonster).y+gvara);
  3102.             if(missile[0].status==1)
  3103.             {
  3104.                 if(within(missile[0].x+6,missile[0].y+6,(*mymonster).x,
  3105.                     (*mymonster).y,4,32))
  3106.                 {
  3107.                     missile[0].status=2;
  3108.                     missile[0].transit=0;
  3109.                     missile[0].dir=rebound[missile[0].dir];
  3110.                 }
  3111.             }
  3112.             break;
  3113.         case EGGLES:
  3114.             (*mymonster).transit++;
  3115.             if((*mymonster).transit==8 && (Random()&1)==0) (*mymonster).transit--;
  3116.             if((*mymonster).transit>7) (*mymonster).transit=0;
  3117.             dir=getdir((*mymonster).x,(*mymonster).y);
  3118.             if((*mymonster).dir!=dir)
  3119.             {
  3120.                 if((*mymonster).alt1++>12)
  3121.                 {
  3122.                     (*mymonster).alt1=0;
  3123.                     (*mymonster).dir=dir;
  3124.                 }
  3125.             }
  3126.             (*mymonster).pic=egglewalkpic[(*mymonster).dir][(*mymonster).transit>>1];
  3127.             occumaster=3;
  3128.             if((*mymonster).transit<6)
  3129.                 cango(&(*mymonster).x,&(*mymonster).y,
  3130.                     dir1x[(*mymonster).dir],dir1y[(*mymonster).dir],(*mymonster).dir,15);
  3131.             if(missile[0].status==1)
  3132.             {
  3133.                 if(within(missile[0].x+6,missile[0].y+6,(*mymonster).x,
  3134.                     (*mymonster).y,4,16))
  3135.                 {
  3136.                     missile[0].status=2;
  3137.                     missile[0].transit=0;
  3138.                     (*mymonster).status=4;
  3139.                     minidraw(47,(*mymonster).x,
  3140.                         (*mymonster).y+bounce[(*mymonster).transit]);
  3141.                     (*mymonster).transit=23;
  3142.                     score+=1;
  3143.                     sounder(gsndchannelc,eephandle);
  3144.                     displayscore();
  3145.                     return;
  3146.                 }
  3147.             }
  3148.             minidraw((*mymonster).pic,(*mymonster).x,
  3149.                     (*mymonster).y+bounce[(*mymonster).transit]);
  3150.             if ((*mymonster).alt2) (*mymonster).alt2--;
  3151.             else if(within(plx,ply,(*mymonster).x,(*mymonster).y,33,17))
  3152.             {
  3153.                 sounder(gsndchannelc,ouchhandle);
  3154.                 healtht=healtht-8;
  3155.                 (*mymonster).alt2=16;
  3156.             }
  3157.             break;
  3158.         case ICECREAM:
  3159.             (*mymonster).transit=(++(*mymonster).transit)&31;
  3160.             (*mymonster).x+=dir1x[(*mymonster).dir];
  3161.             (*mymonster).x+=diricex[(*mymonster).transit>>2];
  3162.             (*mymonster).y+=dir1y[(*mymonster).dir];
  3163.             (*mymonster).y+=diricey[(*mymonster).transit>>2];
  3164.             mondraw(49,(*mymonster).x,(*mymonster).y);
  3165.             if(within(plx,ply,(*mymonster).x,(*mymonster).y,24,24))
  3166.             {
  3167.                 sounder(gsndchannelc,yumhandle);
  3168.                 healtht=MAXHEALTH;
  3169.                 (*mymonster).status=DEAD;
  3170.                 (*mymonster).transit=22;
  3171.             }
  3172.             if((*mymonster).x>(MAXLWIDTH*32+32)||(*mymonster).x<-32)
  3173.             {
  3174.                 (*mymonster).status=DEAD;
  3175.                 (*mymonster).transit=22;
  3176.             }
  3177.             break;
  3178.  
  3179.     }
  3180. }
  3181. /**getdir**/
  3182. int    getdir(int x,int y)
  3183. {
  3184.     if(x<plx && y>ply)        return(4);
  3185.     if(x>plx && y>ply)        return(5);
  3186.     if(x>plx && y<ply)        return(6);
  3187.     if(x<plx && y<ply)        return(7);
  3188.     if (x<plx && y==ply)    return(0);
  3189.     if (x>plx && y==ply)    return(1);
  3190.     if (x==plx && y>ply)    return(2);
  3191.     if (x==plx && y<ply)    return(3);
  3192.     return(0);
  3193. }
  3194. /**getdir2**/
  3195. /*a variation of the above with more vertical and horizontal*/
  3196. int    getdir2(int x,int y)
  3197. {
  3198.     if (x<plx && y<ply+32 && y>ply-32) return(0);
  3199.     if (x>plx && y<ply+32 && y>ply-32) return(1);
  3200.     if (x<plx+32 && x>plx-32 && y>ply) return(2);
  3201.     if (x<plx+32 && x>plx-32 && y<ply) return(3);
  3202.     if(x<plx && y>ply) return(4);
  3203.     if(x>plx && y>ply) return(5);
  3204.     if(x>plx && y<ply) return(6);
  3205.     if(x<plx && y<ply) return(7);
  3206.     return(0);
  3207. }
  3208.  
  3209. /**ispressed**/
  3210. /*this functions returns a boolean TRUE if keyboard scan code is pressed*/
  3211. Boolean    ispressed(unsigned short    k)
  3212. {
  3213. /*    unsigned char km[16];*/
  3214.     
  3215.     GetKeys((long *)gkm);
  3216.     return((gkm[k>>3]>>(k&7))&1);
  3217. }
  3218. /**ispressed2**/
  3219. /*similar to version 1 but does not call get keys*/
  3220. Boolean    ispressed2(unsigned short    k)
  3221. {
  3222.     return((gkm[k>>3]>>(k&7))&1);
  3223. }
  3224.  
  3225.  
  3226. /***can go***/
  3227. /*this routine takes x,y,xmod,ymod,direction, size and
  3228. returns legal x and y after modification*/
  3229. void    cango(int *x,int *y,int xmod,int ymod,int direction,int size)
  3230. {
  3231.     int    temp;
  3232.     
  3233.     if (occuval[thislevel[*y>>5][*x>>5]]||
  3234.         occuval[thislevel[*y>>5][(*x+size)>>5]]||
  3235.         occuval[thislevel[(*y+size)>>5][*x>>5]]||
  3236.         occuval[thislevel[(*y+size)>>5][(*x+size)>>5]])
  3237.     {
  3238.         *x=*x+xmod;
  3239.         *y=*y+ymod;
  3240.         direction=8;    /*if already encased let us out*/
  3241.     }
  3242.     switch(direction)
  3243.     {
  3244.         case 0:
  3245.             if (!occupied(*x+xmod+size,*y) && !occupied(*x+xmod+size,*y+size))
  3246.             {
  3247.                 *x=*x+xmod;
  3248.                 break;
  3249.             }
  3250.             if (!occupied(*x+xmod+size,*y) && occupied(*x+xmod+size,*y+size))
  3251.             {
  3252.                 if (!occupied(*x,*y-2) && !occupied(*x+size,*y-2))
  3253.                 {
  3254.                     *y=*y-2;
  3255.                     break;
  3256.                 }
  3257.             }
  3258.             if (occupied(*x+xmod+size,*y) && !occupied(*x+xmod+size,*y+size))
  3259.             {
  3260.                 if (!occupied(*x,*y+2+size) && !occupied(*x+size,*y+2+size))
  3261.                 {
  3262.                     *y=*y+2;
  3263.                     break;
  3264.                 }
  3265.             }
  3266.             break;
  3267.         case 1:
  3268.             if (!occupied(*x+xmod,*y) && !occupied(*x+xmod,*y+size))
  3269.             {
  3270.                 *x=*x+xmod;
  3271.                 break;
  3272.             }
  3273.             if (!occupied(*x+xmod,*y) && occupied(*x+xmod,*y+size))
  3274.             {
  3275.                 if (!occupied(*x,*y-2) && !occupied(*x+size,*y-2))
  3276.                 {
  3277.                     *y=*y-2;
  3278.                     break;
  3279.                 }
  3280.             }
  3281.             if (occupied(*x+xmod,*y) && !occupied(*x+xmod,*y+size))
  3282.             {
  3283.                 if (!occupied(*x,*y+2+size) && !occupied(*x+size,*y+2+size))
  3284.                 {
  3285.                     *y=*y+2;
  3286.                     break;
  3287.                 }
  3288.             }
  3289.             break;
  3290.         case 2:
  3291.             if (!occupied(*x,*y+ymod) && !occupied(*x+size,*y+ymod))
  3292.             {
  3293.                 *y=*y+ymod;
  3294.                 break;
  3295.             }
  3296.             if (!occupied(*x,*y+ymod) && occupied(*x+size,*y+ymod))
  3297.             {
  3298.                 if (!occupied(*x-2,*y) && !occupied(*x-2,*y+size))
  3299.                 {
  3300.                     *x=*x-2;
  3301.                     break;
  3302.                 }
  3303.             }
  3304.             if (occupied(*x,*y+ymod) && !occupied(*x+size,*y+ymod))
  3305.             {
  3306.                 if (!occupied(*x+2+size,*y) && !occupied(*x+2+size,*y+size))
  3307.                 {
  3308.                     *x=*x+2;
  3309.                     break;
  3310.                 }
  3311.             }
  3312.             break;
  3313.         case 3:
  3314.             if (!occupied(*x,*y+ymod+size) && !occupied(*x+size,*y+ymod+size))
  3315.             {
  3316.                 *y=*y+ymod;
  3317.                 break;
  3318.             }
  3319.             if (!occupied(*x,*y+ymod+size) && occupied(*x+size,*y+ymod+size))
  3320.             {
  3321.                 if (!occupied(*x-2,*y) && !occupied(*x-2,*y+size))
  3322.                 {
  3323.                     *x=*x-2;
  3324.                     break;
  3325.                 }
  3326.             }
  3327.             if (occupied(*x,*y+ymod+size) && !occupied(*x+size,*y+ymod+size))
  3328.             {
  3329.                 if (!occupied(*x+2+size,*y) && !occupied(*x+2+size,*y+size))
  3330.                 {
  3331.                     *x=*x+2;
  3332.                     break;
  3333.                 }
  3334.             }
  3335.             break;
  3336.         case 4:
  3337.         case 5:
  3338.         case 6:
  3339.         case 7:
  3340.             if (!occupied(*x+xmod+size,*y+ymod) &&
  3341.                 !occupied(*x+xmod,*y+ymod) &&
  3342.                 !occupied(*x+xmod+size,*y+ymod+size) &&
  3343.                 !occupied(*x+xmod,*y+ymod+size))
  3344.                 {
  3345.                     *x+=xmod;
  3346.                     *y+=ymod;
  3347.                     break;
  3348.                 }
  3349.             else if (occupied(*x+xmod+size,*y)==0 &&
  3350.                 occupied(*x+xmod+size,*y+size)==0 &&
  3351.                 occupied(*x+xmod,*y)==0 &&
  3352.                 occupied(*x+xmod,*y+size)==0)
  3353.                 {
  3354.                 *x=*x+xmod;
  3355.                 break;
  3356.                 }
  3357.             else if (occupied(*x,*y+ymod)==0 &&
  3358.                 occupied(*x+size,*y+ymod)==0 &&
  3359.                 occupied(*x,*y+ymod+size)==0 &&
  3360.                 occupied(*x+size,*y+ymod+size)==0)
  3361.                 {
  3362.                 *y=*y+ymod;
  3363.                 break;
  3364.                 }
  3365.     occumaster=0;
  3366.     }
  3367. }
  3368. /***can go2***/
  3369. /*this routine takes x,y,xmod,ymod,direction, size and
  3370. returns legal x and y after modification
  3371. it is similar to can go but has less smoothing
  3372. for things moving cardinally*/
  3373. void    cango2(int *x,int *y,int xmod,int ymod,int direction,int size)
  3374. {
  3375.     int    temp;
  3376.     
  3377.     if (occuval[thislevel[*y>>5][*x>>5]]||
  3378.         occuval[thislevel[*y>>5][(*x+size)>>5]]||
  3379.         occuval[thislevel[(*y+size)>>5][*x>>5]]||
  3380.         occuval[thislevel[(*y+size)>>5][(*x+size)>>5]])
  3381.     {
  3382.         *x=*x+xmod;
  3383.         *y=*y+ymod;
  3384.         direction=8;    /*if already encased let us out*/
  3385.     }
  3386.     switch(direction)
  3387.     {
  3388.         case 0:
  3389.             if (!occupied(*x+xmod+size,*y) && !occupied(*x+xmod+size,*y+size))
  3390.             {
  3391.                 *x=*x+xmod;
  3392.                 break;
  3393.             }
  3394.             if (!occupied(*x+xmod+size,*y+size-9) && occupied(*x+xmod+size,*y+size))
  3395.             {
  3396.                 if (!occupied(*x,*y-2) && !occupied(*x+size,*y-2))
  3397.                 {
  3398.                     *y=*y-2;
  3399.                     break;
  3400.                 }
  3401.             }
  3402.             if (occupied(*x+xmod+size,*y) && !occupied(*x+xmod+size,*y+9))
  3403.             {
  3404.                 if (!occupied(*x,*y+2+size) && !occupied(*x+size,*y+2+size))
  3405.                 {
  3406.                     *y=*y+2;
  3407.                     break;
  3408.                 }
  3409.             }
  3410.             break;
  3411.         case 1:
  3412.             if (!occupied(*x+xmod,*y) && !occupied(*x+xmod,*y+size))
  3413.             {
  3414.                 *x=*x+xmod;
  3415.                 break;
  3416.             }
  3417.             if (!occupied(*x+xmod,*y+size-9) && occupied(*x+xmod,*y+size))
  3418.             {
  3419.                 if (!occupied(*x,*y-2) && !occupied(*x+size,*y-2))
  3420.                 {
  3421.                     *y=*y-2;
  3422.                     break;
  3423.                 }
  3424.             }
  3425.             if (occupied(*x+xmod,*y) && !occupied(*x+xmod,*y+9))
  3426.             {
  3427.                 if (!occupied(*x,*y+2+size) && !occupied(*x+size,*y+2+size))
  3428.                 {
  3429.                     *y=*y+2;
  3430.                     break;
  3431.                 }
  3432.             }
  3433.             break;
  3434.         case 2:
  3435.             if (!occupied(*x,*y+ymod) && !occupied(*x+size,*y+ymod))
  3436.             {
  3437.                 *y=*y+ymod;
  3438.                 break;
  3439.             }
  3440.             if (!occupied(*x+size-9,*y+ymod) && occupied(*x+size,*y+ymod))
  3441.             {
  3442.                 if (!occupied(*x-2,*y) && !occupied(*x-2,*y+size))
  3443.                 {
  3444.                     *x=*x-2;
  3445.                     break;
  3446.                 }
  3447.             }
  3448.             if (occupied(*x,*y+ymod) && !occupied(*x+9,*y+ymod))
  3449.             {
  3450.                 if (!occupied(*x+2+size,*y) && !occupied(*x+2+size,*y+size))
  3451.                 {
  3452.                     *x=*x+2;
  3453.                     break;
  3454.                 }
  3455.             }
  3456.             break;
  3457.         case 3:
  3458.             if (!occupied(*x,*y+ymod+size) && !occupied(*x+size,*y+ymod+size))
  3459.             {
  3460.                 *y=*y+ymod;
  3461.                 break;
  3462.             }
  3463.             if (!occupied(*x+size-9,*y+ymod+size) && occupied(*x+size,*y+ymod+size))
  3464.             {
  3465.                 if (!occupied(*x-2,*y) && !occupied(*x-2,*y+size))
  3466.                 {
  3467.                     *x=*x-2;
  3468.                     break;
  3469.                 }
  3470.             }
  3471.             if (occupied(*x,*y+ymod+size) && !occupied(*x+9,*y+ymod+size))
  3472.             {
  3473.                 if (!occupied(*x+2+size,*y) && !occupied(*x+2+size,*y+size))
  3474.                 {
  3475.                     *x=*x+2;
  3476.                     break;
  3477.                 }
  3478.             }
  3479.             break;
  3480.         case 4:
  3481.         case 5:
  3482.         case 6:
  3483.         case 7:
  3484.             if (!occupied(*x+xmod+size,*y+ymod) &&
  3485.                 !occupied(*x+xmod,*y+ymod) &&
  3486.                 !occupied(*x+xmod+size,*y+ymod+size) &&
  3487.                 !occupied(*x+xmod,*y+ymod+size))
  3488.                 {
  3489.                     *x+=xmod;
  3490.                     *y+=ymod;
  3491.                     break;
  3492.                 }
  3493.             else if (occupied(*x+xmod+size,*y)==0 &&
  3494.                 occupied(*x+xmod+size,*y+size)==0 &&
  3495.                 occupied(*x+xmod,*y)==0 &&
  3496.                 occupied(*x+xmod,*y+size)==0)
  3497.                 {
  3498.                 *x=*x+xmod;
  3499.                 break;
  3500.                 }
  3501.             else if (occupied(*x,*y+ymod)==0 &&
  3502.                 occupied(*x+size,*y+ymod)==0 &&
  3503.                 occupied(*x,*y+ymod+size)==0 &&
  3504.                 occupied(*x+size,*y+ymod+size)==0)
  3505.                 {
  3506.                 *y=*y+ymod;
  3507.                 break;
  3508.                 }
  3509.     occumaster=0;
  3510.     }
  3511. }
  3512. /**occupied**/
  3513. /*this function takes absolute coordinates and returns
  3514.  a nonzero if occupied, 0 if the space is empty*/
  3515. Boolean    occupied(int x,int y)
  3516. {
  3517.     register int    value,loop;
  3518.     switch(occumaster)
  3519.     {
  3520.         case 0:    /*sense only landscape*/
  3521.             return(occuval[thislevel[y>>5][x>>5]]);
  3522.             break;
  3523.         case 1:    /*sense player and sense monsters except number gloop*/
  3524.             value=occuval[thislevel[y>>5][x>>5]];
  3525.             if(value==0)
  3526.             {
  3527.                 for(loop=nummonsters;loop>=0;loop--)
  3528.                 {
  3529.                     if (monster[loop].status>=32 && loop!=gloop)
  3530.                     {
  3531.                         if (x>monster[loop].x && x<monster[loop].x+32 &&
  3532.                             y>monster[loop].y && y<monster[loop].y+32)
  3533.                             value=1;
  3534.                     }
  3535.                 }
  3536.                 if (x>plx && x<plx+32 && y>ply && y<ply+32
  3537.                     && masterstatus==STATUS_GAME) value=1;
  3538.             }
  3539.             return(value);
  3540.             break;
  3541.         case 2:    /*sense monsters*/
  3542.             value=occuval[thislevel[y>>5][x>>5]];
  3543.             if(value==0)
  3544.             {
  3545.                 for(loop=nummonsters;loop>=0;loop--)
  3546.                 {
  3547.                     if (monster[loop].status>=32)
  3548.                     {
  3549.                         if (x>monster[loop].x && x<monster[loop].x+32 &&
  3550.                             y>monster[loop].y && y<monster[loop].y+32)
  3551.                             value=1;
  3552.                     }
  3553.                 }
  3554.             }
  3555.             return(value);
  3556.             break;
  3557.         case 3:    /*sense eggles*/
  3558.             value=occuval[thislevel[y>>5][x>>5]];
  3559.             if(value==0)
  3560.             {
  3561.                 for(loop=nummonsters;loop>=0;loop--)
  3562.                 {
  3563.                     if (monster[loop].status==EGGLES && loop!=gloop)
  3564.                     {
  3565.                         if (x>monster[loop].x && x<monster[loop].x+16 &&
  3566.                             y>monster[loop].y && y<monster[loop].y+16)
  3567.                             value=1;
  3568.                     }
  3569.                 }
  3570.             }
  3571.             return(value);
  3572.             break;
  3573.     }
  3574. }
  3575.  
  3576.  
  3577.  
  3578. /*** helpdialog ***/
  3579. helpdialog(void)
  3580. {
  3581.     Boolean    dialogDone=FALSE;
  3582.     short            itemHit;
  3583.     short        itemType;
  3584.     Rect        itemRect;
  3585.     Handle        itemHandle;
  3586.     DialogPtr    helpdiaptr;
  3587.     short        loop,x,y;
  3588.     Point        p;
  3589.     PicHandle    temppict;
  3590.     UniversalProcPtr    mypicproc;
  3591.     UniversalProcPtr    mydiafilter;
  3592.  
  3593.     InitCursor();
  3594.     helpdiaptr=GetNewDialog(402,NIL_POINTER,(WindowPtr)MOVE_TO_FRONT);
  3595.     gcard=0;
  3596.     /*p.h=370; p.v=20;
  3597.     LocalToGlobal(&p);
  3598.     MoveWindow(helpdiaptr,p.h,p.v,FALSE);*/
  3599.  
  3600.         
  3601.     mypicproc=NewRoutineDescriptor((ProcPtr)pictproc,uppUserItemProcInfo,GetCurrentISA());
  3602.     GetDItem(helpdiaptr,4,&itemType,&itemHandle,&itemRect);
  3603.     SetDItem(helpdiaptr,4,itemType,(Handle)mypicproc,&itemRect);
  3604.  
  3605.     DrawDialog(helpdiaptr);
  3606.     ShowWindow(helpdiaptr);
  3607.     SetPort(helpdiaptr);
  3608.     
  3609.     while(dialogDone==FALSE)
  3610.     {
  3611.         mydiafilter=NewRoutineDescriptor((ProcPtr)helpfilter,uppModalFilterProcInfo,GetCurrentISA());
  3612.         ModalDialog((ModalFilterUPP)mydiafilter,&itemHit);
  3613.         switch(itemHit)
  3614.         {
  3615.             case 1:    /*ok*/
  3616.                 HideWindow(helpdiaptr);
  3617.                 dialogDone=TRUE;
  3618.                 break;
  3619.             case 2:    /*left*/
  3620.                 if(--gcard<0) gcard=2;
  3621.                 DrawDialog(helpdiaptr);
  3622.                 break;
  3623.             case 3: /*right*/
  3624.                 if(++gcard>4) gcard=0;
  3625.                 DrawDialog(helpdiaptr);
  3626.                 break;
  3627.             case 4: /*center*/
  3628.                 if(gcard==0)
  3629.                 {
  3630.                     HideWindow(helpdiaptr);
  3631.                     dialogDone=TRUE;
  3632.                 }
  3633.                 else
  3634.                 {    /*send to first card*/
  3635.                     gcard=0;
  3636.                     DrawDialog(helpdiaptr);
  3637.                 }
  3638.                 break;
  3639.             default:
  3640.                 break;
  3641.         }
  3642.     }
  3643.     DisposDialog(helpdiaptr);
  3644.     SetPort(myWindow);
  3645. }
  3646. /**helpfilter**/
  3647. pascal Boolean helpfilter(DialogPtr theDlg,EventRecord *theEvent,
  3648.     short *itemHit )
  3649. {
  3650.     short    loop;
  3651.     short    x,y;
  3652.     Point    p;
  3653.     Rect    myrect;
  3654.     
  3655.     p=theEvent->where;
  3656.     GlobalToLocal(&p);
  3657.     if(theEvent->what==mouseDown)
  3658.     {
  3659.         SetRect(&myrect,352,224,382,254);
  3660.         if(PtInRect(p,&myrect))
  3661.         {
  3662.             InvertRect(&myrect);
  3663.             while (Button())
  3664.             {
  3665.             }
  3666.             InvertRect(&myrect);
  3667.             *itemHit=3;
  3668.             return(TRUE);
  3669.         }
  3670.         SetRect(&myrect,2,224,32,254);
  3671.         if(PtInRect(p,&myrect))
  3672.         {
  3673.             InvertRect(&myrect);
  3674.             while (Button())
  3675.             {
  3676.             }
  3677.             InvertRect(&myrect);
  3678.             *itemHit=2;
  3679.             return(TRUE);
  3680.         }
  3681.         SetRect(&myrect,34,224,350,254);
  3682.         if(PtInRect(p,&myrect))
  3683.         {
  3684.             InvertRect(&myrect);
  3685.             while (Button())
  3686.             {
  3687.             }
  3688.             InvertRect(&myrect);
  3689.             *itemHit=4;
  3690.             return(TRUE);
  3691.         }
  3692.  
  3693.         *itemHit = ok;
  3694.         return( TRUE );    // Note: pascal-style TRUE
  3695.     }
  3696.  
  3697.     if ( theEvent->what != keyDown )    // just looking for keystrokes
  3698.         return(FALSE);
  3699.  
  3700.     switch ( (theEvent->message) & charCodeMask ) {
  3701.         case 0x0d:    // Return pressed or ...
  3702.         case 0x03:    // ... Enter pressed
  3703.         case 0x1b:    // Esc pressed
  3704.             *itemHit = ok;
  3705.             return( TRUE );    // Note: pascal-style TRUE
  3706.         default:
  3707.             return( FALSE );    // all others
  3708.     }
  3709. }
  3710.  
  3711. //*proc to draw pict*/
  3712. pascal void pictproc(WindowPtr theDlg,short theItem )
  3713. {
  3714.     Rect    iRect;
  3715.     Handle    iHndl;
  3716.     short    iType;
  3717.  
  3718.     /*GetDItem (theDlg, 1, &iType, &iHndl, &iRect );*/
  3719.     LDR(gbasepic+51+gcard,0,0);
  3720. }
  3721.  
  3722. /*** quitdialog ***/
  3723. quitdialog(void)
  3724. {
  3725.     Boolean    dialogDone=FALSE;
  3726.     short            itemHit;
  3727.     short        itemType;
  3728.     Rect        itemRect;
  3729.     Handle        itemHandle;
  3730.     DialogPtr    quitdiaptr;
  3731.     short        loop,x,y;
  3732.     Point        p;
  3733.     UniversalProcPtr    mydiafilter;
  3734.     UniversalProcPtr    myokproc;
  3735.  
  3736.     InitCursor();
  3737.     quitdiaptr=GetNewDialog(403,NIL_POINTER,(WindowPtr)MOVE_TO_FRONT);
  3738.     myokproc=NewRoutineDescriptor((ProcPtr)okitemproc,uppUserItemProcInfo,GetCurrentISA());
  3739.     GetDItem(quitdiaptr,4,&itemType,&itemHandle,&itemRect);
  3740.     SetDItem(quitdiaptr,4,itemType,(Handle)myokproc,&itemRect);
  3741.  
  3742.     DrawDialog(quitdiaptr);
  3743.     ShowWindow(quitdiaptr);
  3744.     SetPort(quitdiaptr);
  3745.     
  3746.     while(dialogDone==FALSE)
  3747.     {
  3748.         mydiafilter=NewRoutineDescriptor((ProcPtr)diafilter,uppModalFilterProcInfo,GetCurrentISA());
  3749.         ModalDialog((ModalFilterUPP)mydiafilter,&itemHit);
  3750.         switch(itemHit)
  3751.         {
  3752.             case 1:    /*ok*/
  3753.                 HideWindow(quitdiaptr);
  3754.                 dialogDone=TRUE;
  3755.                 masterstatus=STATUS_QUIT;
  3756.                 break;
  3757.             case 2:    /*cancel*/
  3758.                 HideWindow(quitdiaptr);
  3759.                 dialogDone=TRUE;
  3760.                 break;
  3761.             default:
  3762.                 break;
  3763.         }
  3764.     }
  3765.     DisposDialog(quitdiaptr);
  3766.     SetPort(myWindow);
  3767. }
  3768.